@zigrivers/scaffold 3.28.0 → 3.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/content/guides/.gitkeep +0 -0
- package/content/guides/index.html +1188 -0
- package/content/guides/mmr/.diagrams/diagram-0.svg +1 -0
- package/content/guides/mmr/.diagrams/manifest.json +3 -0
- package/content/guides/mmr/index.html +1728 -0
- package/content/guides/mmr/index.md +403 -0
- package/content/knowledge/VERSION +1 -0
- package/content/knowledge/backend/backend-api-design.md +8 -0
- package/content/knowledge/backend/backend-architecture.md +8 -0
- package/content/knowledge/backend/backend-async-patterns.md +7 -0
- package/content/knowledge/backend/backend-auth-patterns.md +9 -0
- package/content/knowledge/backend/backend-conventions.md +6 -0
- package/content/knowledge/backend/backend-data-modeling.md +7 -0
- package/content/knowledge/backend/backend-deployment.md +8 -0
- package/content/knowledge/backend/backend-dev-environment.md +5 -0
- package/content/knowledge/backend/backend-fintech-broker-integration.md +6 -0
- package/content/knowledge/backend/backend-fintech-compliance.md +10 -2
- package/content/knowledge/backend/backend-fintech-data-modeling.md +6 -0
- package/content/knowledge/backend/backend-fintech-ledger.md +6 -0
- package/content/knowledge/backend/backend-fintech-observability.md +6 -0
- package/content/knowledge/backend/backend-fintech-order-lifecycle.md +6 -0
- package/content/knowledge/backend/backend-fintech-risk-management.md +6 -0
- package/content/knowledge/backend/backend-fintech-testing.md +6 -0
- package/content/knowledge/backend/backend-observability.md +7 -0
- package/content/knowledge/backend/backend-project-structure.md +6 -0
- package/content/knowledge/backend/backend-requirements.md +6 -0
- package/content/knowledge/backend/backend-security.md +7 -0
- package/content/knowledge/backend/backend-testing.md +7 -0
- package/content/knowledge/backend/backend-worker-patterns.md +6 -0
- package/content/knowledge/browser-extension/browser-extension-architecture.md +6 -0
- package/content/knowledge/browser-extension/browser-extension-content-scripts.md +6 -0
- package/content/knowledge/browser-extension/browser-extension-conventions.md +6 -0
- package/content/knowledge/browser-extension/browser-extension-cross-browser.md +6 -0
- package/content/knowledge/browser-extension/browser-extension-dev-environment.md +6 -0
- package/content/knowledge/browser-extension/browser-extension-manifest.md +6 -0
- package/content/knowledge/browser-extension/browser-extension-project-structure.md +6 -0
- package/content/knowledge/browser-extension/browser-extension-requirements.md +6 -0
- package/content/knowledge/browser-extension/browser-extension-security.md +7 -0
- package/content/knowledge/browser-extension/browser-extension-service-workers.md +6 -0
- package/content/knowledge/browser-extension/browser-extension-store-submission.md +6 -0
- package/content/knowledge/browser-extension/browser-extension-testing.md +6 -0
- package/content/knowledge/cli/cli-architecture.md +4 -0
- package/content/knowledge/cli/cli-conventions.md +4 -0
- package/content/knowledge/cli/cli-dev-environment.md +5 -0
- package/content/knowledge/cli/cli-distribution-patterns.md +5 -0
- package/content/knowledge/cli/cli-interactivity-patterns.md +4 -0
- package/content/knowledge/cli/cli-output-patterns.md +4 -0
- package/content/knowledge/cli/cli-project-structure.md +4 -0
- package/content/knowledge/cli/cli-requirements.md +4 -0
- package/content/knowledge/cli/cli-shell-integration.md +4 -0
- package/content/knowledge/cli/cli-testing.md +4 -0
- package/content/knowledge/core/adr-craft.md +8 -0
- package/content/knowledge/core/ai-memory-management.md +6 -0
- package/content/knowledge/core/api-design.md +6 -0
- package/content/knowledge/core/automated-review-tooling.md +8 -0
- package/content/knowledge/core/claude-md-patterns.md +8 -0
- package/content/knowledge/core/coding-conventions.md +8 -0
- package/content/knowledge/core/database-design.md +8 -0
- package/content/knowledge/core/design-system-tokens.md +8 -0
- package/content/knowledge/core/dev-environment.md +4 -0
- package/content/knowledge/core/domain-modeling.md +6 -0
- package/content/knowledge/core/eval-craft.md +6 -0
- package/content/knowledge/core/git-workflow-patterns.md +8 -0
- package/content/knowledge/core/multi-model-research-dispatch.md +6 -0
- package/content/knowledge/core/multi-model-review-dispatch.md +6 -0
- package/content/knowledge/core/multi-service-api-contracts.md +5 -0
- package/content/knowledge/core/multi-service-architecture.md +5 -0
- package/content/knowledge/core/multi-service-auth.md +6 -0
- package/content/knowledge/core/multi-service-data-ownership.md +8 -0
- package/content/knowledge/core/multi-service-observability.md +8 -0
- package/content/knowledge/core/multi-service-resilience.md +5 -0
- package/content/knowledge/core/multi-service-task-decomposition.md +8 -0
- package/content/knowledge/core/multi-service-testing.md +5 -0
- package/content/knowledge/core/operations-runbook.md +8 -0
- package/content/knowledge/core/project-structure-patterns.md +4 -0
- package/content/knowledge/core/review-step-template.md +4 -0
- package/content/knowledge/core/security-best-practices.md +6 -0
- package/content/knowledge/core/system-architecture.md +6 -0
- package/content/knowledge/core/task-decomposition.md +5 -0
- package/content/knowledge/core/task-tracking.md +8 -0
- package/content/knowledge/core/tech-stack-selection.md +8 -0
- package/content/knowledge/core/test-skeleton-generation.md +4 -0
- package/content/knowledge/core/testing-strategy.md +8 -0
- package/content/knowledge/core/user-stories.md +8 -0
- package/content/knowledge/core/user-story-innovation.md +4 -0
- package/content/knowledge/core/ux-specification.md +5 -0
- package/content/knowledge/data-pipeline/data-pipeline-architecture.md +5 -0
- package/content/knowledge/data-pipeline/data-pipeline-batch-patterns.md +4 -0
- package/content/knowledge/data-pipeline/data-pipeline-conventions.md +4 -0
- package/content/knowledge/data-pipeline/data-pipeline-dev-environment.md +4 -0
- package/content/knowledge/data-pipeline/data-pipeline-orchestration.md +4 -0
- package/content/knowledge/data-pipeline/data-pipeline-project-structure.md +4 -0
- package/content/knowledge/data-pipeline/data-pipeline-quality.md +4 -0
- package/content/knowledge/data-pipeline/data-pipeline-requirements.md +4 -0
- package/content/knowledge/data-pipeline/data-pipeline-schema-management.md +4 -0
- package/content/knowledge/data-pipeline/data-pipeline-security.md +4 -0
- package/content/knowledge/data-pipeline/data-pipeline-streaming-patterns.md +4 -0
- package/content/knowledge/data-pipeline/data-pipeline-testing.md +4 -0
- package/content/knowledge/data-science/data-science-architecture.md +5 -0
- package/content/knowledge/data-science/data-science-conventions.md +6 -0
- package/content/knowledge/data-science/data-science-data-versioning.md +6 -0
- package/content/knowledge/data-science/data-science-dev-environment.md +6 -0
- package/content/knowledge/data-science/data-science-experiment-tracking.md +8 -0
- package/content/knowledge/data-science/data-science-model-evaluation.md +5 -0
- package/content/knowledge/data-science/data-science-notebook-discipline.md +5 -0
- package/content/knowledge/data-science/data-science-observability.md +6 -0
- package/content/knowledge/data-science/data-science-project-structure.md +5 -0
- package/content/knowledge/data-science/data-science-reproducibility.md +8 -0
- package/content/knowledge/data-science/data-science-requirements.md +5 -0
- package/content/knowledge/data-science/data-science-security.md +8 -0
- package/content/knowledge/data-science/data-science-testing.md +5 -0
- package/content/knowledge/execution/enhancement-workflow.md +4 -0
- package/content/knowledge/execution/multi-agent-coordination.md +12 -1
- package/content/knowledge/execution/task-claiming-strategy.md +4 -0
- package/content/knowledge/execution/tdd-execution-loop.md +5 -0
- package/content/knowledge/execution/worktree-management.md +5 -0
- package/content/knowledge/finalization/apply-fixes-and-freeze.md +4 -0
- package/content/knowledge/finalization/developer-onboarding.md +4 -0
- package/content/knowledge/finalization/implementation-playbook.md +4 -0
- package/content/knowledge/game/game-accessibility.md +4 -0
- package/content/knowledge/game/game-ai-patterns.md +4 -0
- package/content/knowledge/game/game-asset-pipeline.md +4 -0
- package/content/knowledge/game/game-audio-design.md +4 -0
- package/content/knowledge/game/game-binary-vcs-strategy.md +5 -0
- package/content/knowledge/game/game-design-document.md +4 -0
- package/content/knowledge/game/game-domain-patterns.md +4 -0
- package/content/knowledge/game/game-economy-design.md +4 -0
- package/content/knowledge/game/game-engine-selection.md +4 -0
- package/content/knowledge/game/game-ideation.md +4 -0
- package/content/knowledge/game/game-input-systems.md +4 -0
- package/content/knowledge/game/game-level-content-design.md +4 -0
- package/content/knowledge/game/game-liveops-analytics.md +4 -0
- package/content/knowledge/game/game-localization.md +4 -0
- package/content/knowledge/game/game-milestone-definitions.md +4 -0
- package/content/knowledge/game/game-modding-ugc.md +4 -0
- package/content/knowledge/game/game-narrative-design.md +4 -0
- package/content/knowledge/game/game-networking.md +4 -0
- package/content/knowledge/game/game-performance-budgeting.md +4 -0
- package/content/knowledge/game/game-platform-certification.md +6 -0
- package/content/knowledge/game/game-project-structure.md +4 -0
- package/content/knowledge/game/game-save-systems.md +4 -0
- package/content/knowledge/game/game-testing-strategy.md +4 -0
- package/content/knowledge/game/game-ui-patterns.md +4 -0
- package/content/knowledge/game/game-vr-ar-design.md +6 -0
- package/content/knowledge/library/library-api-design.md +4 -0
- package/content/knowledge/library/library-architecture.md +4 -0
- package/content/knowledge/library/library-bundling.md +4 -0
- package/content/knowledge/library/library-conventions.md +5 -0
- package/content/knowledge/library/library-dev-environment.md +4 -0
- package/content/knowledge/library/library-documentation.md +4 -0
- package/content/knowledge/library/library-project-structure.md +4 -0
- package/content/knowledge/library/library-requirements.md +4 -0
- package/content/knowledge/library/library-security.md +4 -0
- package/content/knowledge/library/library-testing.md +4 -0
- package/content/knowledge/library/library-type-definitions.md +4 -0
- package/content/knowledge/library/library-versioning.md +5 -0
- package/content/knowledge/ml/ml-architecture.md +4 -0
- package/content/knowledge/ml/ml-conventions.md +4 -0
- package/content/knowledge/ml/ml-dev-environment.md +4 -0
- package/content/knowledge/ml/ml-experiment-tracking.md +6 -0
- package/content/knowledge/ml/ml-model-evaluation.md +4 -0
- package/content/knowledge/ml/ml-observability.md +5 -0
- package/content/knowledge/ml/ml-project-structure.md +4 -0
- package/content/knowledge/ml/ml-requirements.md +4 -0
- package/content/knowledge/ml/ml-security.md +5 -0
- package/content/knowledge/ml/ml-serving-patterns.md +4 -0
- package/content/knowledge/ml/ml-testing.md +4 -0
- package/content/knowledge/ml/ml-training-patterns.md +4 -0
- package/content/knowledge/mobile-app/mobile-app-architecture.md +6 -0
- package/content/knowledge/mobile-app/mobile-app-conventions.md +6 -0
- package/content/knowledge/mobile-app/mobile-app-deployment.md +6 -0
- package/content/knowledge/mobile-app/mobile-app-dev-environment.md +6 -0
- package/content/knowledge/mobile-app/mobile-app-distribution.md +6 -0
- package/content/knowledge/mobile-app/mobile-app-observability.md +7 -0
- package/content/knowledge/mobile-app/mobile-app-offline-patterns.md +7 -0
- package/content/knowledge/mobile-app/mobile-app-project-structure.md +6 -0
- package/content/knowledge/mobile-app/mobile-app-push-notifications.md +6 -0
- package/content/knowledge/mobile-app/mobile-app-requirements.md +7 -0
- package/content/knowledge/mobile-app/mobile-app-security.md +8 -0
- package/content/knowledge/mobile-app/mobile-app-testing.md +6 -0
- package/content/knowledge/product/gap-analysis.md +4 -0
- package/content/knowledge/product/ideation-craft.md +4 -0
- package/content/knowledge/product/prd-craft.md +4 -0
- package/content/knowledge/product/prd-innovation.md +4 -0
- package/content/knowledge/product/vision-craft.md +4 -0
- package/content/knowledge/product/vision-innovation.md +4 -0
- package/content/knowledge/research/research-architecture.md +4 -0
- package/content/knowledge/research/research-conventions.md +6 -0
- package/content/knowledge/research/research-dev-environment.md +6 -0
- package/content/knowledge/research/research-experiment-loop.md +4 -0
- package/content/knowledge/research/research-experiment-tracking.md +6 -0
- package/content/knowledge/research/research-ml-architecture-search.md +4 -0
- package/content/knowledge/research/research-ml-evaluation.md +4 -0
- package/content/knowledge/research/research-ml-experiment-tracking.md +6 -0
- package/content/knowledge/research/research-ml-training-patterns.md +4 -0
- package/content/knowledge/research/research-observability.md +5 -0
- package/content/knowledge/research/research-overfitting-prevention.md +5 -0
- package/content/knowledge/research/research-project-structure.md +5 -0
- package/content/knowledge/research/research-quant-backtesting.md +4 -0
- package/content/knowledge/research/research-quant-market-data.md +4 -0
- package/content/knowledge/research/research-quant-metrics.md +4 -0
- package/content/knowledge/research/research-quant-requirements.md +4 -0
- package/content/knowledge/research/research-quant-risk.md +4 -0
- package/content/knowledge/research/research-quant-strategy-patterns.md +4 -0
- package/content/knowledge/research/research-requirements.md +5 -0
- package/content/knowledge/research/research-security.md +5 -0
- package/content/knowledge/research/research-sim-compute-management.md +4 -0
- package/content/knowledge/research/research-sim-engine-patterns.md +4 -0
- package/content/knowledge/research/research-sim-parameter-spaces.md +4 -0
- package/content/knowledge/research/research-sim-validation.md +4 -0
- package/content/knowledge/research/research-testing.md +5 -0
- package/content/knowledge/review/review-adr.md +6 -0
- package/content/knowledge/review/review-api-design.md +6 -0
- package/content/knowledge/review/review-art-bible.md +4 -0
- package/content/knowledge/review/review-database-design.md +5 -0
- package/content/knowledge/review/review-domain-modeling.md +5 -0
- package/content/knowledge/review/review-game-design.md +4 -0
- package/content/knowledge/review/review-game-economy.md +4 -0
- package/content/knowledge/review/review-game-ui.md +5 -0
- package/content/knowledge/review/review-implementation-tasks.md +5 -0
- package/content/knowledge/review/review-methodology.md +4 -0
- package/content/knowledge/review/review-netcode.md +4 -0
- package/content/knowledge/review/review-operations.md +6 -0
- package/content/knowledge/review/review-platform-cert.md +4 -0
- package/content/knowledge/review/review-prd.md +4 -0
- package/content/knowledge/review/review-security.md +7 -0
- package/content/knowledge/review/review-system-architecture.md +6 -0
- package/content/knowledge/review/review-testing-strategy.md +6 -0
- package/content/knowledge/review/review-user-stories.md +5 -0
- package/content/knowledge/review/review-ux-specification.md +6 -0
- package/content/knowledge/review/review-vision.md +4 -0
- package/content/knowledge/tools/post-implementation-review-methodology.md +4 -0
- package/content/knowledge/tools/release-management.md +5 -0
- package/content/knowledge/tools/session-analysis.md +4 -0
- package/content/knowledge/tools/version-strategy.md +4 -0
- package/content/knowledge/validation/critical-path-analysis.md +4 -0
- package/content/knowledge/validation/cross-phase-consistency.md +4 -0
- package/content/knowledge/validation/decision-completeness.md +5 -0
- package/content/knowledge/validation/dependency-validation.md +4 -0
- package/content/knowledge/validation/implementability-review.md +4 -0
- package/content/knowledge/validation/scope-management.md +4 -0
- package/content/knowledge/validation/traceability.md +4 -0
- package/content/knowledge/web-app/web-app-api-patterns.md +6 -0
- package/content/knowledge/web-app/web-app-architecture.md +6 -0
- package/content/knowledge/web-app/web-app-auth-patterns.md +9 -0
- package/content/knowledge/web-app/web-app-conventions.md +5 -0
- package/content/knowledge/web-app/web-app-data-patterns.md +6 -0
- package/content/knowledge/web-app/web-app-deployment-workflow.md +6 -0
- package/content/knowledge/web-app/web-app-deployment.md +6 -0
- package/content/knowledge/web-app/web-app-design-system.md +6 -0
- package/content/knowledge/web-app/web-app-dev-environment.md +6 -0
- package/content/knowledge/web-app/web-app-observability.md +6 -0
- package/content/knowledge/web-app/web-app-project-structure.md +5 -0
- package/content/knowledge/web-app/web-app-rendering-strategies.md +6 -0
- package/content/knowledge/web-app/web-app-requirements.md +6 -0
- package/content/knowledge/web-app/web-app-security.md +8 -0
- package/content/knowledge/web-app/web-app-session-patterns.md +7 -0
- package/content/knowledge/web-app/web-app-testing.md +6 -0
- package/content/knowledge/web-app/web-app-ux-patterns.md +6 -0
- package/content/knowledge/web3/web3-access-control.md +8 -0
- package/content/knowledge/web3/web3-architecture.md +7 -0
- package/content/knowledge/web3/web3-audit-workflow.md +7 -0
- package/content/knowledge/web3/web3-common-vulnerabilities.md +8 -0
- package/content/knowledge/web3/web3-conventions.md +6 -0
- package/content/knowledge/web3/web3-deployment-and-verification.md +7 -0
- package/content/knowledge/web3/web3-dev-environment.md +6 -0
- package/content/knowledge/web3/web3-gas-optimization.md +7 -0
- package/content/knowledge/web3/web3-oracles-and-external-data.md +7 -0
- package/content/knowledge/web3/web3-project-structure.md +6 -0
- package/content/knowledge/web3/web3-requirements.md +6 -0
- package/content/knowledge/web3/web3-security.md +8 -0
- package/content/knowledge/web3/web3-testing.md +6 -0
- package/content/knowledge/web3/web3-upgradeability.md +7 -0
- package/content/tools/knowledge-audit-entry.md +79 -0
- package/content/tools/review-code.md +41 -14
- package/content/tools/review-pr.md +32 -14
- package/dist/cli/commands/dashboard.d.ts +1 -1
- package/dist/cli/commands/dashboard.d.ts.map +1 -1
- package/dist/cli/commands/dashboard.js +10 -10
- package/dist/cli/commands/dashboard.js.map +1 -1
- package/dist/cli/commands/dashboard.test.js +1 -1
- package/dist/cli/commands/dashboard.test.js.map +1 -1
- package/dist/cli/commands/guides.d.ts +24 -0
- package/dist/cli/commands/guides.d.ts.map +1 -0
- package/dist/cli/commands/guides.js +103 -0
- package/dist/cli/commands/guides.js.map +1 -0
- package/dist/cli/commands/knowledge-freshness-anti-over-rewrite.d.ts +9 -0
- package/dist/cli/commands/knowledge-freshness-anti-over-rewrite.d.ts.map +1 -0
- package/dist/cli/commands/knowledge-freshness-anti-over-rewrite.js +112 -0
- package/dist/cli/commands/knowledge-freshness-anti-over-rewrite.js.map +1 -0
- package/dist/cli/commands/knowledge-freshness-audit-apply.d.ts +8 -0
- package/dist/cli/commands/knowledge-freshness-audit-apply.d.ts.map +1 -0
- package/dist/cli/commands/knowledge-freshness-audit-apply.js +96 -0
- package/dist/cli/commands/knowledge-freshness-audit-apply.js.map +1 -0
- package/dist/cli/commands/knowledge-freshness-audit-prefilter.d.ts +7 -0
- package/dist/cli/commands/knowledge-freshness-audit-prefilter.d.ts.map +1 -0
- package/dist/cli/commands/knowledge-freshness-audit-prefilter.js +42 -0
- package/dist/cli/commands/knowledge-freshness-audit-prefilter.js.map +1 -0
- package/dist/cli/commands/knowledge-freshness-audit-run-entry.d.ts +9 -0
- package/dist/cli/commands/knowledge-freshness-audit-run-entry.d.ts.map +1 -0
- package/dist/cli/commands/knowledge-freshness-audit-run-entry.js +63 -0
- package/dist/cli/commands/knowledge-freshness-audit-run-entry.js.map +1 -0
- package/dist/cli/commands/knowledge-freshness-bump-version.d.ts +8 -0
- package/dist/cli/commands/knowledge-freshness-bump-version.d.ts.map +1 -0
- package/dist/cli/commands/knowledge-freshness-bump-version.js +34 -0
- package/dist/cli/commands/knowledge-freshness-bump-version.js.map +1 -0
- package/dist/cli/commands/knowledge-freshness-deep-guidance-check.d.ts +7 -0
- package/dist/cli/commands/knowledge-freshness-deep-guidance-check.d.ts.map +1 -0
- package/dist/cli/commands/knowledge-freshness-deep-guidance-check.js +51 -0
- package/dist/cli/commands/knowledge-freshness-deep-guidance-check.js.map +1 -0
- package/dist/cli/commands/knowledge-freshness-link-check.d.ts +7 -0
- package/dist/cli/commands/knowledge-freshness-link-check.d.ts.map +1 -0
- package/dist/cli/commands/knowledge-freshness-link-check.js +57 -0
- package/dist/cli/commands/knowledge-freshness-link-check.js.map +1 -0
- package/dist/cli/commands/knowledge-freshness-lint-unsourced.d.ts +8 -0
- package/dist/cli/commands/knowledge-freshness-lint-unsourced.d.ts.map +1 -0
- package/dist/cli/commands/knowledge-freshness-lint-unsourced.js +58 -0
- package/dist/cli/commands/knowledge-freshness-lint-unsourced.js.map +1 -0
- package/dist/cli/commands/knowledge-freshness.d.ts +4 -0
- package/dist/cli/commands/knowledge-freshness.d.ts.map +1 -0
- package/dist/cli/commands/knowledge-freshness.js +25 -0
- package/dist/cli/commands/knowledge-freshness.js.map +1 -0
- package/dist/cli/commands/observe.d.ts +4 -0
- package/dist/cli/commands/observe.d.ts.map +1 -1
- package/dist/cli/commands/observe.js +13 -0
- package/dist/cli/commands/observe.js.map +1 -1
- package/dist/cli/commands/observe.test.js +46 -0
- package/dist/cli/commands/observe.test.js.map +1 -1
- package/dist/cli/commands/validate-knowledge.d.ts +4 -0
- package/dist/cli/commands/validate-knowledge.d.ts.map +1 -0
- package/dist/cli/commands/validate-knowledge.js +32 -0
- package/dist/cli/commands/validate-knowledge.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +6 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/adapters/claude-code.d.ts.map +1 -1
- package/dist/core/adapters/claude-code.js +6 -3
- package/dist/core/adapters/claude-code.js.map +1 -1
- package/dist/core/adapters/claude-code.test.js +45 -1
- package/dist/core/adapters/claude-code.test.js.map +1 -1
- package/dist/core/assembly/engine.d.ts.map +1 -1
- package/dist/core/assembly/engine.js +7 -3
- package/dist/core/assembly/engine.js.map +1 -1
- package/dist/core/assembly/engine.test.js +45 -1
- package/dist/core/assembly/engine.test.js.map +1 -1
- package/dist/core/assembly/gap-signal-tail.d.ts +18 -0
- package/dist/core/assembly/gap-signal-tail.d.ts.map +1 -0
- package/dist/core/assembly/gap-signal-tail.js +43 -0
- package/dist/core/assembly/gap-signal-tail.js.map +1 -0
- package/dist/core/assembly/gap-signal-tail.test.d.ts +2 -0
- package/dist/core/assembly/gap-signal-tail.test.d.ts.map +1 -0
- package/dist/core/assembly/gap-signal-tail.test.js +49 -0
- package/dist/core/assembly/gap-signal-tail.test.js.map +1 -0
- package/dist/core/assembly/knowledge-loader.d.ts +11 -0
- package/dist/core/assembly/knowledge-loader.d.ts.map +1 -1
- package/dist/core/assembly/knowledge-loader.js +54 -1
- package/dist/core/assembly/knowledge-loader.js.map +1 -1
- package/dist/core/assembly/knowledge-loader.test.js +73 -0
- package/dist/core/assembly/knowledge-loader.test.js.map +1 -1
- package/dist/guides/build.d.ts +12 -0
- package/dist/guides/build.d.ts.map +1 -0
- package/dist/guides/build.js +50 -0
- package/dist/guides/build.js.map +1 -0
- package/dist/guides/build.test.d.ts +2 -0
- package/dist/guides/build.test.d.ts.map +1 -0
- package/dist/guides/build.test.js +74 -0
- package/dist/guides/build.test.js.map +1 -0
- package/dist/guides/chrome.d.ts +24 -0
- package/dist/guides/chrome.d.ts.map +1 -0
- package/dist/guides/chrome.js +118 -0
- package/dist/guides/chrome.js.map +1 -0
- package/dist/guides/cli-guides.test.d.ts +2 -0
- package/dist/guides/cli-guides.test.d.ts.map +1 -0
- package/dist/guides/cli-guides.test.js +41 -0
- package/dist/guides/cli-guides.test.js.map +1 -0
- package/dist/guides/dashboard-theme.css +1073 -0
- package/dist/guides/directives-callout.test.d.ts +2 -0
- package/dist/guides/directives-callout.test.d.ts.map +1 -0
- package/dist/guides/directives-callout.test.js +22 -0
- package/dist/guides/directives-callout.test.js.map +1 -0
- package/dist/guides/directives-chart.test.d.ts +2 -0
- package/dist/guides/directives-chart.test.d.ts.map +1 -0
- package/dist/guides/directives-chart.test.js +25 -0
- package/dist/guides/directives-chart.test.js.map +1 -0
- package/dist/guides/directives-filter-table.test.d.ts +2 -0
- package/dist/guides/directives-filter-table.test.d.ts.map +1 -0
- package/dist/guides/directives-filter-table.test.js +22 -0
- package/dist/guides/directives-filter-table.test.js.map +1 -0
- package/dist/guides/directives-sev.test.d.ts +2 -0
- package/dist/guides/directives-sev.test.d.ts.map +1 -0
- package/dist/guides/directives-sev.test.js +15 -0
- package/dist/guides/directives-sev.test.js.map +1 -0
- package/dist/guides/directives-tabs.test.d.ts +2 -0
- package/dist/guides/directives-tabs.test.d.ts.map +1 -0
- package/dist/guides/directives-tabs.test.js +52 -0
- package/dist/guides/directives-tabs.test.js.map +1 -0
- package/dist/guides/directives.d.ts +7 -0
- package/dist/guides/directives.d.ts.map +1 -0
- package/dist/guides/directives.js +158 -0
- package/dist/guides/directives.js.map +1 -0
- package/dist/guides/fs-guides.test.d.ts +2 -0
- package/dist/guides/fs-guides.test.d.ts.map +1 -0
- package/dist/guides/fs-guides.test.js +14 -0
- package/dist/guides/fs-guides.test.js.map +1 -0
- package/dist/guides/index-page.d.ts +3 -0
- package/dist/guides/index-page.d.ts.map +1 -0
- package/dist/guides/index-page.js +14 -0
- package/dist/guides/index-page.js.map +1 -0
- package/dist/guides/lint.d.ts +6 -0
- package/dist/guides/lint.d.ts.map +1 -0
- package/dist/guides/lint.js +27 -0
- package/dist/guides/lint.js.map +1 -0
- package/dist/guides/lint.test.d.ts +2 -0
- package/dist/guides/lint.test.d.ts.map +1 -0
- package/dist/guides/lint.test.js +24 -0
- package/dist/guides/lint.test.js.map +1 -0
- package/dist/guides/loader.d.ts +4 -0
- package/dist/guides/loader.d.ts.map +1 -0
- package/dist/guides/loader.js +63 -0
- package/dist/guides/loader.js.map +1 -0
- package/dist/guides/loader.test.d.ts +2 -0
- package/dist/guides/loader.test.d.ts.map +1 -0
- package/dist/guides/loader.test.js +85 -0
- package/dist/guides/loader.test.js.map +1 -0
- package/dist/guides/mermaid-sanitize.test.d.ts +2 -0
- package/dist/guides/mermaid-sanitize.test.d.ts.map +1 -0
- package/dist/guides/mermaid-sanitize.test.js +57 -0
- package/dist/guides/mermaid-sanitize.test.js.map +1 -0
- package/dist/guides/mermaid.d.ts +18 -0
- package/dist/guides/mermaid.d.ts.map +1 -0
- package/dist/guides/mermaid.js +137 -0
- package/dist/guides/mermaid.js.map +1 -0
- package/dist/guides/mermaid.test.d.ts +2 -0
- package/dist/guides/mermaid.test.d.ts.map +1 -0
- package/dist/guides/mermaid.test.js +105 -0
- package/dist/guides/mermaid.test.js.map +1 -0
- package/dist/guides/render.d.ts +12 -0
- package/dist/guides/render.d.ts.map +1 -0
- package/dist/guides/render.js +58 -0
- package/dist/guides/render.js.map +1 -0
- package/dist/guides/render.test.d.ts +2 -0
- package/dist/guides/render.test.d.ts.map +1 -0
- package/dist/guides/render.test.js +46 -0
- package/dist/guides/render.test.js.map +1 -0
- package/dist/guides/sanitize.d.ts +3 -0
- package/dist/guides/sanitize.d.ts.map +1 -0
- package/dist/guides/sanitize.js +76 -0
- package/dist/guides/sanitize.js.map +1 -0
- package/dist/guides/sanitize.test.d.ts +2 -0
- package/dist/guides/sanitize.test.d.ts.map +1 -0
- package/dist/guides/sanitize.test.js +45 -0
- package/dist/guides/sanitize.test.js.map +1 -0
- package/dist/guides/template.d.ts +11 -0
- package/dist/guides/template.d.ts.map +1 -0
- package/dist/guides/template.js +38 -0
- package/dist/guides/template.js.map +1 -0
- package/dist/guides/template.test.d.ts +2 -0
- package/dist/guides/template.test.d.ts.map +1 -0
- package/dist/guides/template.test.js +41 -0
- package/dist/guides/template.test.js.map +1 -0
- package/dist/guides/types.d.ts +20 -0
- package/dist/guides/types.d.ts.map +1 -0
- package/dist/guides/types.js +2 -0
- package/dist/guides/types.js.map +1 -0
- package/dist/knowledge-freshness/audit-apply-pr.d.ts +64 -0
- package/dist/knowledge-freshness/audit-apply-pr.d.ts.map +1 -0
- package/dist/knowledge-freshness/audit-apply-pr.js +309 -0
- package/dist/knowledge-freshness/audit-apply-pr.js.map +1 -0
- package/dist/knowledge-freshness/audit-apply-pr.test.d.ts +2 -0
- package/dist/knowledge-freshness/audit-apply-pr.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/audit-apply-pr.test.js +211 -0
- package/dist/knowledge-freshness/audit-apply-pr.test.js.map +1 -0
- package/dist/knowledge-freshness/audit-apply.d.ts +16 -0
- package/dist/knowledge-freshness/audit-apply.d.ts.map +1 -0
- package/dist/knowledge-freshness/audit-apply.js +193 -0
- package/dist/knowledge-freshness/audit-apply.js.map +1 -0
- package/dist/knowledge-freshness/audit-apply.test.d.ts +2 -0
- package/dist/knowledge-freshness/audit-apply.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/audit-apply.test.js +482 -0
- package/dist/knowledge-freshness/audit-apply.test.js.map +1 -0
- package/dist/knowledge-freshness/audit-prefilter.d.ts +12 -0
- package/dist/knowledge-freshness/audit-prefilter.d.ts.map +1 -0
- package/dist/knowledge-freshness/audit-prefilter.js +74 -0
- package/dist/knowledge-freshness/audit-prefilter.js.map +1 -0
- package/dist/knowledge-freshness/audit-prefilter.test.d.ts +2 -0
- package/dist/knowledge-freshness/audit-prefilter.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/audit-prefilter.test.js +78 -0
- package/dist/knowledge-freshness/audit-prefilter.test.js.map +1 -0
- package/dist/knowledge-freshness/audit-runner.d.ts +135 -0
- package/dist/knowledge-freshness/audit-runner.d.ts.map +1 -0
- package/dist/knowledge-freshness/audit-runner.js +168 -0
- package/dist/knowledge-freshness/audit-runner.js.map +1 -0
- package/dist/knowledge-freshness/audit-runner.test.d.ts +2 -0
- package/dist/knowledge-freshness/audit-runner.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/audit-runner.test.js +130 -0
- package/dist/knowledge-freshness/audit-runner.test.js.map +1 -0
- package/dist/knowledge-freshness/bump-version.d.ts +24 -0
- package/dist/knowledge-freshness/bump-version.d.ts.map +1 -0
- package/dist/knowledge-freshness/bump-version.js +69 -0
- package/dist/knowledge-freshness/bump-version.js.map +1 -0
- package/dist/knowledge-freshness/bump-version.test.d.ts +2 -0
- package/dist/knowledge-freshness/bump-version.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/bump-version.test.js +82 -0
- package/dist/knowledge-freshness/bump-version.test.js.map +1 -0
- package/dist/knowledge-freshness/gates/anti-over-rewrite.d.ts +86 -0
- package/dist/knowledge-freshness/gates/anti-over-rewrite.d.ts.map +1 -0
- package/dist/knowledge-freshness/gates/anti-over-rewrite.js +210 -0
- package/dist/knowledge-freshness/gates/anti-over-rewrite.js.map +1 -0
- package/dist/knowledge-freshness/gates/anti-over-rewrite.test.d.ts +2 -0
- package/dist/knowledge-freshness/gates/anti-over-rewrite.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/gates/anti-over-rewrite.test.js +115 -0
- package/dist/knowledge-freshness/gates/anti-over-rewrite.test.js.map +1 -0
- package/dist/knowledge-freshness/gates/changed-files.d.ts +53 -0
- package/dist/knowledge-freshness/gates/changed-files.d.ts.map +1 -0
- package/dist/knowledge-freshness/gates/changed-files.js +128 -0
- package/dist/knowledge-freshness/gates/changed-files.js.map +1 -0
- package/dist/knowledge-freshness/gates/deep-guidance-check.d.ts +23 -0
- package/dist/knowledge-freshness/gates/deep-guidance-check.d.ts.map +1 -0
- package/dist/knowledge-freshness/gates/deep-guidance-check.js +27 -0
- package/dist/knowledge-freshness/gates/deep-guidance-check.js.map +1 -0
- package/dist/knowledge-freshness/gates/deep-guidance-check.test.d.ts +2 -0
- package/dist/knowledge-freshness/gates/deep-guidance-check.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/gates/deep-guidance-check.test.js +23 -0
- package/dist/knowledge-freshness/gates/deep-guidance-check.test.js.map +1 -0
- package/dist/knowledge-freshness/gates/link-check.d.ts +55 -0
- package/dist/knowledge-freshness/gates/link-check.d.ts.map +1 -0
- package/dist/knowledge-freshness/gates/link-check.js +161 -0
- package/dist/knowledge-freshness/gates/link-check.js.map +1 -0
- package/dist/knowledge-freshness/gates/link-check.test.d.ts +2 -0
- package/dist/knowledge-freshness/gates/link-check.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/gates/link-check.test.js +76 -0
- package/dist/knowledge-freshness/gates/link-check.test.js.map +1 -0
- package/dist/knowledge-freshness/gates/lint-unsourced.d.ts +40 -0
- package/dist/knowledge-freshness/gates/lint-unsourced.d.ts.map +1 -0
- package/dist/knowledge-freshness/gates/lint-unsourced.js +143 -0
- package/dist/knowledge-freshness/gates/lint-unsourced.js.map +1 -0
- package/dist/knowledge-freshness/gates/lint-unsourced.test.d.ts +2 -0
- package/dist/knowledge-freshness/gates/lint-unsourced.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/gates/lint-unsourced.test.js +68 -0
- package/dist/knowledge-freshness/gates/lint-unsourced.test.js.map +1 -0
- package/dist/knowledge-freshness/gates/parse-entry.d.ts +25 -0
- package/dist/knowledge-freshness/gates/parse-entry.d.ts.map +1 -0
- package/dist/knowledge-freshness/gates/parse-entry.js +41 -0
- package/dist/knowledge-freshness/gates/parse-entry.js.map +1 -0
- package/dist/knowledge-freshness/gates/parse-entry.test.d.ts +2 -0
- package/dist/knowledge-freshness/gates/parse-entry.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/gates/parse-entry.test.js +34 -0
- package/dist/knowledge-freshness/gates/parse-entry.test.js.map +1 -0
- package/dist/knowledge-freshness/providers/anthropic.d.ts +33 -0
- package/dist/knowledge-freshness/providers/anthropic.d.ts.map +1 -0
- package/dist/knowledge-freshness/providers/anthropic.js +36 -0
- package/dist/knowledge-freshness/providers/anthropic.js.map +1 -0
- package/dist/knowledge-freshness/providers/anthropic.test.d.ts +2 -0
- package/dist/knowledge-freshness/providers/anthropic.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/providers/anthropic.test.js +32 -0
- package/dist/knowledge-freshness/providers/anthropic.test.js.map +1 -0
- package/dist/knowledge-freshness/providers/deepseek.d.ts +33 -0
- package/dist/knowledge-freshness/providers/deepseek.d.ts.map +1 -0
- package/dist/knowledge-freshness/providers/deepseek.js +157 -0
- package/dist/knowledge-freshness/providers/deepseek.js.map +1 -0
- package/dist/knowledge-freshness/providers/deepseek.test.d.ts +2 -0
- package/dist/knowledge-freshness/providers/deepseek.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/providers/deepseek.test.js +142 -0
- package/dist/knowledge-freshness/providers/deepseek.test.js.map +1 -0
- package/dist/knowledge-freshness/providers/index.d.ts +41 -0
- package/dist/knowledge-freshness/providers/index.d.ts.map +1 -0
- package/dist/knowledge-freshness/providers/index.js +108 -0
- package/dist/knowledge-freshness/providers/index.js.map +1 -0
- package/dist/knowledge-freshness/providers/index.test.d.ts +2 -0
- package/dist/knowledge-freshness/providers/index.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/providers/index.test.js +97 -0
- package/dist/knowledge-freshness/providers/index.test.js.map +1 -0
- package/dist/knowledge-freshness/source-hash.d.ts +39 -0
- package/dist/knowledge-freshness/source-hash.d.ts.map +1 -0
- package/dist/knowledge-freshness/source-hash.js +180 -0
- package/dist/knowledge-freshness/source-hash.js.map +1 -0
- package/dist/knowledge-freshness/source-hash.test.d.ts +2 -0
- package/dist/knowledge-freshness/source-hash.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/source-hash.test.js +63 -0
- package/dist/knowledge-freshness/source-hash.test.js.map +1 -0
- package/dist/knowledge-freshness/source-url-validator.d.ts +57 -0
- package/dist/knowledge-freshness/source-url-validator.d.ts.map +1 -0
- package/dist/knowledge-freshness/source-url-validator.js +304 -0
- package/dist/knowledge-freshness/source-url-validator.js.map +1 -0
- package/dist/knowledge-freshness/source-url-validator.test.d.ts +2 -0
- package/dist/knowledge-freshness/source-url-validator.test.d.ts.map +1 -0
- package/dist/knowledge-freshness/source-url-validator.test.js +167 -0
- package/dist/knowledge-freshness/source-url-validator.test.js.map +1 -0
- package/dist/observability/checks/lens-i-knowledge-gaps.d.ts +3 -0
- package/dist/observability/checks/lens-i-knowledge-gaps.d.ts.map +1 -0
- package/dist/observability/checks/lens-i-knowledge-gaps.js +165 -0
- package/dist/observability/checks/lens-i-knowledge-gaps.js.map +1 -0
- package/dist/observability/checks/lens-i-knowledge-gaps.test.d.ts +2 -0
- package/dist/observability/checks/lens-i-knowledge-gaps.test.d.ts.map +1 -0
- package/dist/observability/checks/lens-i-knowledge-gaps.test.js +421 -0
- package/dist/observability/checks/lens-i-knowledge-gaps.test.js.map +1 -0
- package/dist/observability/checks/lens-i-lessons-scanner.d.ts +16 -0
- package/dist/observability/checks/lens-i-lessons-scanner.d.ts.map +1 -0
- package/dist/observability/checks/lens-i-lessons-scanner.js +106 -0
- package/dist/observability/checks/lens-i-lessons-scanner.js.map +1 -0
- package/dist/observability/checks/lens-i-lessons-scanner.test.d.ts +2 -0
- package/dist/observability/checks/lens-i-lessons-scanner.test.d.ts.map +1 -0
- package/dist/observability/checks/lens-i-lessons-scanner.test.js +174 -0
- package/dist/observability/checks/lens-i-lessons-scanner.test.js.map +1 -0
- package/dist/observability/engine/api.d.ts +4 -0
- package/dist/observability/engine/api.d.ts.map +1 -1
- package/dist/observability/engine/api.js +17 -1
- package/dist/observability/engine/api.js.map +1 -1
- package/dist/observability/engine/checks/observability-config.d.ts +4 -0
- package/dist/observability/engine/checks/observability-config.d.ts.map +1 -1
- package/dist/observability/engine/checks/observability-config.js +1 -0
- package/dist/observability/engine/checks/observability-config.js.map +1 -1
- package/dist/observability/engine/checks/registry.d.ts.map +1 -1
- package/dist/observability/engine/checks/registry.js +7 -0
- package/dist/observability/engine/checks/registry.js.map +1 -1
- package/dist/observability/engine/checks/registry.test.js +3 -2
- package/dist/observability/engine/checks/registry.test.js.map +1 -1
- package/dist/observability/engine/checks/runner.d.ts +30 -0
- package/dist/observability/engine/checks/runner.d.ts.map +1 -1
- package/dist/observability/engine/checks/runner.js +8 -1
- package/dist/observability/engine/checks/runner.js.map +1 -1
- package/dist/observability/engine/checks/runner.test.js +74 -0
- package/dist/observability/engine/checks/runner.test.js.map +1 -1
- package/dist/observability/engine/event-schemas.d.ts.map +1 -1
- package/dist/observability/engine/event-schemas.js +41 -3
- package/dist/observability/engine/event-schemas.js.map +1 -1
- package/dist/observability/engine/event-schemas.test.js +105 -0
- package/dist/observability/engine/event-schemas.test.js.map +1 -1
- package/dist/observability/engine/fix-flow.d.ts +7 -0
- package/dist/observability/engine/fix-flow.d.ts.map +1 -1
- package/dist/observability/engine/fix-flow.js +5 -3
- package/dist/observability/engine/fix-flow.js.map +1 -1
- package/dist/observability/engine/knowledge-root-integration.test.d.ts +2 -0
- package/dist/observability/engine/knowledge-root-integration.test.d.ts.map +1 -0
- package/dist/observability/engine/knowledge-root-integration.test.js +103 -0
- package/dist/observability/engine/knowledge-root-integration.test.js.map +1 -0
- package/dist/observability/engine/types.d.ts +20 -1
- package/dist/observability/engine/types.d.ts.map +1 -1
- package/dist/observability/engine/types.test.js +1 -1
- package/dist/observability/engine/types.test.js.map +1 -1
- package/dist/observability/knowledge-index.d.ts +145 -0
- package/dist/observability/knowledge-index.d.ts.map +1 -0
- package/dist/observability/knowledge-index.js +353 -0
- package/dist/observability/knowledge-index.js.map +1 -0
- package/dist/observability/knowledge-index.test.d.ts +2 -0
- package/dist/observability/knowledge-index.test.d.ts.map +1 -0
- package/dist/observability/knowledge-index.test.js +364 -0
- package/dist/observability/knowledge-index.test.js.map +1 -0
- package/dist/observability/renderers/markdown.d.ts.map +1 -1
- package/dist/observability/renderers/markdown.js +14 -0
- package/dist/observability/renderers/markdown.js.map +1 -1
- package/dist/observability/renderers/markdown.test.js +30 -0
- package/dist/observability/renderers/markdown.test.js.map +1 -1
- package/dist/types/assembly.d.ts +10 -0
- package/dist/types/assembly.d.ts.map +1 -1
- package/dist/utils/fs.d.ts +6 -0
- package/dist/utils/fs.d.ts.map +1 -1
- package/dist/utils/fs.js +13 -0
- package/dist/utils/fs.js.map +1 -1
- package/dist/validation/knowledge-frontmatter-validator.d.ts +15 -0
- package/dist/validation/knowledge-frontmatter-validator.d.ts.map +1 -0
- package/dist/validation/knowledge-frontmatter-validator.js +131 -0
- package/dist/validation/knowledge-frontmatter-validator.js.map +1 -0
- package/dist/validation/knowledge-frontmatter-validator.test.d.ts +2 -0
- package/dist/validation/knowledge-frontmatter-validator.test.d.ts.map +1 -0
- package/dist/validation/knowledge-frontmatter-validator.test.js +66 -0
- package/dist/validation/knowledge-frontmatter-validator.test.js.map +1 -0
- package/package.json +13 -4
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import yaml from 'js-yaml';
|
|
4
|
+
/**
|
|
5
|
+
* One-sentence summary of the verdict's source list. Used in the PR title
|
|
6
|
+
* (which has length limits) so the operator sees at a glance which doc the
|
|
7
|
+
* audit is calibrated against.
|
|
8
|
+
*/
|
|
9
|
+
function oneSentenceSourceSummary(verdict) {
|
|
10
|
+
const urls = verdict.sources_checked.map((s) => s.url);
|
|
11
|
+
if (urls.length === 0)
|
|
12
|
+
return '(no sources)';
|
|
13
|
+
if (urls.length === 1)
|
|
14
|
+
return urls[0];
|
|
15
|
+
return `${urls[0]} and ${urls.length - 1} other source(s)`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Markdown-escape a cell so a stray `|` or backtick in a finding doesn't
|
|
19
|
+
* break the table layout. We don't try to render arbitrary markdown — the
|
|
20
|
+
* cell is a single line of plain text.
|
|
21
|
+
*/
|
|
22
|
+
function escapeCell(s) {
|
|
23
|
+
// Round-7 F-004 follow-through: collapse ALL JS line terminators so
|
|
24
|
+
// table cells can't smuggle in a BREAKING CHANGE: footer via lone \r
|
|
25
|
+
// or Unicode line separators.
|
|
26
|
+
return s
|
|
27
|
+
.replace(/\|/g, '\\|')
|
|
28
|
+
.replace(/[\r\n\u2028\u2029]+/g, ' ')
|
|
29
|
+
.trim();
|
|
30
|
+
}
|
|
31
|
+
export function renderFindingsTable(verdict) {
|
|
32
|
+
if (verdict.findings.length === 0) {
|
|
33
|
+
return '_No findings._';
|
|
34
|
+
}
|
|
35
|
+
const header = '| severity | drift_kind | claim_in_entry | evidence_url |';
|
|
36
|
+
const sep = '|---|---|---|---|';
|
|
37
|
+
const rows = verdict.findings.map((f) => {
|
|
38
|
+
const severity = escapeCell(f.severity);
|
|
39
|
+
const driftKind = escapeCell(f.drift_kind);
|
|
40
|
+
const claim = escapeCell(f.claim_in_entry);
|
|
41
|
+
const evidence = escapeCell(f.evidence_url);
|
|
42
|
+
return `| ${severity} | ${driftKind} | ${claim} | ${evidence} |`;
|
|
43
|
+
});
|
|
44
|
+
return [header, sep, ...rows].join('\n');
|
|
45
|
+
}
|
|
46
|
+
export function renderPrTitle(verdict) {
|
|
47
|
+
// Round-8 F-002: sanitize ALL title components — both entry_name and
|
|
48
|
+
// the source summary — so an LLM-injected `\nBREAKING CHANGE:` (via
|
|
49
|
+
// verdict.entry_name or sources_checked[*].url) cannot turn a
|
|
50
|
+
// chore-refresh title into a major-bump signal. The body sanitization
|
|
51
|
+
// alone wasn't enough; deriveBumpKind also reads the title.
|
|
52
|
+
const name = sanitizeLlmField(verdict.entry_name);
|
|
53
|
+
const summary = sanitizeLlmField(oneSentenceSourceSummary(verdict));
|
|
54
|
+
return `chore(knowledge): refresh ${name} against ${summary}`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Collapse ALL JavaScript line terminators in LLM-controlled text before
|
|
58
|
+
* splicing into the PR body. F-003 round-4 introduced this for `\r\n`/`\n`;
|
|
59
|
+
* F-002/F-003/F-004 round-7 extends it to lone `\r` and the Unicode line
|
|
60
|
+
* separators `<U+2028>` / `<U+2029>`, since JS regex multiline-mode `^` treats
|
|
61
|
+
* those as line starts. Without exhaustive sanitization, an LLM-controlled
|
|
62
|
+
* field carrying `\rBREAKING CHANGE:` or `<U+2028>BREAKING CHANGE:` would
|
|
63
|
+
* still inject a major-bump footer that the version-bump workflow honors.
|
|
64
|
+
*
|
|
65
|
+
* Citations of "BREAKING CHANGE:" in evidence text mid-line remain
|
|
66
|
+
* legitimate; the round-2 start-of-line anchor on deriveBumpKind plus the
|
|
67
|
+
* collapsing here ensure such mentions never become footers.
|
|
68
|
+
*/
|
|
69
|
+
function sanitizeLlmField(s) {
|
|
70
|
+
return s.replace(/[\r\n\u2028\u2029]+/g, ' ').trim();
|
|
71
|
+
}
|
|
72
|
+
export function renderPrBody(verdict, opts = {}) {
|
|
73
|
+
const sourceList = verdict.sources_checked.length === 0
|
|
74
|
+
? '_No sources._'
|
|
75
|
+
: verdict.sources_checked.map((s) => `- ${sanitizeLlmField(s.url)}`).join('\n');
|
|
76
|
+
const provenance = verdict.sources_checked.length === 0
|
|
77
|
+
? '_No sources._'
|
|
78
|
+
: verdict.sources_checked
|
|
79
|
+
.map((s) => {
|
|
80
|
+
const u = sanitizeLlmField(s.url);
|
|
81
|
+
const h = sanitizeLlmField(s.content_hash);
|
|
82
|
+
const r = sanitizeLlmField(s.retrieved_at);
|
|
83
|
+
return `- ${u} (${h}, retrieved ${r})`;
|
|
84
|
+
})
|
|
85
|
+
.join('\n');
|
|
86
|
+
const preserveSection = verdict.preserve_warnings.length === 0
|
|
87
|
+
? '_None._'
|
|
88
|
+
: verdict.preserve_warnings.map((w) => `- ${sanitizeLlmField(w)}`).join('\n');
|
|
89
|
+
const mmrLine = opts.mmrJobId
|
|
90
|
+
? `job_id: ${opts.mmrJobId}`
|
|
91
|
+
: '_Not run inline — see knowledge-freshness CI gates._';
|
|
92
|
+
// F-003 round-6: every LLM-controlled scalar that's spliced into the PR
|
|
93
|
+
// body gets `sanitizeLlmField` applied. The Zod schema permits arbitrary
|
|
94
|
+
// strings for `entry_name`/`audit_date`/`model`/`content_hash`/`retrieved_at`,
|
|
95
|
+
// so a verdict containing "\nBREAKING CHANGE:" in any of those would
|
|
96
|
+
// otherwise create a start-of-line footer that deriveBumpKind treats as a
|
|
97
|
+
// real major bump signal. Sanitizing collapses newlines so the rendered
|
|
98
|
+
// body cannot inject a footer regardless of model output.
|
|
99
|
+
return [
|
|
100
|
+
'## Summary',
|
|
101
|
+
`Grounded audit of ${sanitizeLlmField(verdict.entry_name)}.md against:`,
|
|
102
|
+
sourceList,
|
|
103
|
+
'',
|
|
104
|
+
'## Verdict',
|
|
105
|
+
`- verdict: ${sanitizeLlmField(verdict.verdict)}`,
|
|
106
|
+
`- audit_date: ${sanitizeLlmField(verdict.audit_date)}`,
|
|
107
|
+
`- model: ${sanitizeLlmField(verdict.model)}`,
|
|
108
|
+
'',
|
|
109
|
+
'## Findings',
|
|
110
|
+
renderFindingsTable(verdict),
|
|
111
|
+
'',
|
|
112
|
+
'## MMR',
|
|
113
|
+
mmrLine,
|
|
114
|
+
'',
|
|
115
|
+
'## Sources',
|
|
116
|
+
provenance,
|
|
117
|
+
'',
|
|
118
|
+
'## Preserve warnings',
|
|
119
|
+
preserveSection,
|
|
120
|
+
'',
|
|
121
|
+
].join('\n');
|
|
122
|
+
}
|
|
123
|
+
/** UTC YYYY-MM-DD for branch naming. Separate so tests can pin the date. */
|
|
124
|
+
export function todayUtcYmd(now = new Date()) {
|
|
125
|
+
const y = now.getUTCFullYear().toString().padStart(4, '0');
|
|
126
|
+
const m = (now.getUTCMonth() + 1).toString().padStart(2, '0');
|
|
127
|
+
const d = now.getUTCDate().toString().padStart(2, '0');
|
|
128
|
+
return `${y}-${m}-${d}`;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Sanitize an entry name for use as a git branch component. We never
|
|
132
|
+
* interpolate raw user-controlled strings into a shell command, but the
|
|
133
|
+
* entry name does become a branch ref — disallow whitespace, slashes
|
|
134
|
+
* (already a path separator in the prefix), and non-ascii. The on-disk
|
|
135
|
+
* entry names in `content/knowledge/*` are all kebab-case ASCII so this
|
|
136
|
+
* is a safety net, not a transformation.
|
|
137
|
+
*/
|
|
138
|
+
export function sanitizeForBranch(entryName) {
|
|
139
|
+
const cleaned = entryName.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '');
|
|
140
|
+
if (cleaned.length === 0)
|
|
141
|
+
throw new Error(`entry name "${entryName}" sanitized to empty string`);
|
|
142
|
+
return cleaned;
|
|
143
|
+
}
|
|
144
|
+
export function branchNameForEntry(entryName, ymd) {
|
|
145
|
+
return `knowledge-freshness/${sanitizeForBranch(entryName)}-${ymd}`;
|
|
146
|
+
}
|
|
147
|
+
export function renderFreshnessPr(verdict, opts = {}) {
|
|
148
|
+
return {
|
|
149
|
+
title: renderPrTitle(verdict),
|
|
150
|
+
body: renderPrBody(verdict, opts),
|
|
151
|
+
entryName: verdict.entry_name,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/** Volatility-tier → PR label mapping. Used for triage/filtering. */
|
|
155
|
+
export function volatilityLabel(volatility) {
|
|
156
|
+
switch (volatility) {
|
|
157
|
+
case 'fast-moving': return 'volatility:fast-moving';
|
|
158
|
+
case 'evolving': return 'volatility:evolving';
|
|
159
|
+
case 'stable': return 'volatility:stable';
|
|
160
|
+
default: return undefined;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Run a subprocess synchronously and throw on non-zero exit. Captures stdout
|
|
165
|
+
* + stderr in the thrown error so failures surface a useful message rather
|
|
166
|
+
* than a bare exit code.
|
|
167
|
+
*/
|
|
168
|
+
function runOrThrow(cmd, args) {
|
|
169
|
+
const result = spawnSync(cmd, args, { encoding: 'utf8' });
|
|
170
|
+
if (result.status !== 0) {
|
|
171
|
+
const stderr = result.stderr?.trim() ?? '';
|
|
172
|
+
const stdout = result.stdout?.trim() ?? '';
|
|
173
|
+
throw new Error(`command failed: ${cmd} ${args.join(' ')} (exit ${result.status})\n` +
|
|
174
|
+
(stdout ? `stdout: ${stdout}\n` : '') +
|
|
175
|
+
(stderr ? `stderr: ${stderr}` : ''));
|
|
176
|
+
}
|
|
177
|
+
return result.stdout ?? '';
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Open a freshness PR. Pre-conditions:
|
|
181
|
+
* - The on-disk entry at `entryPath` already has the verdict applied.
|
|
182
|
+
* - The git working tree must show ONLY `entryPath` as modified (no other
|
|
183
|
+
* unrelated changes). This is a safety guard so a manual run can't
|
|
184
|
+
* accidentally sweep in unrelated work.
|
|
185
|
+
* - `gh` CLI is authenticated.
|
|
186
|
+
*/
|
|
187
|
+
export function openFreshnessPr(verdict, opts) {
|
|
188
|
+
// Working-tree safety. `git status --porcelain` lists changed paths with a
|
|
189
|
+
// 2-char status prefix. We require exactly one entry, and it must be the
|
|
190
|
+
// entry path. Untracked files outside the entry path are also disallowed —
|
|
191
|
+
// they'd be carried along by `git add <entryPath>` only if the path matches,
|
|
192
|
+
// but a porcelain check is the cleanest precondition.
|
|
193
|
+
const porcelain = runOrThrow('git', ['status', '--porcelain']).split('\n').filter((l) => l.length > 0);
|
|
194
|
+
// Path normalization (round-4 F-001 + round-9 F-002): `git status
|
|
195
|
+
// --porcelain` outputs paths relative to the GIT REPOSITORY ROOT.
|
|
196
|
+
// `opts.entryPath` can be:
|
|
197
|
+
// - absolute → path.resolve is a no-op
|
|
198
|
+
// - relative to cwd → resolve against process.cwd()
|
|
199
|
+
// Always resolve porcelain output against the repo root.
|
|
200
|
+
const repoRoot = runOrThrow('git', ['rev-parse', '--show-toplevel']).trim();
|
|
201
|
+
const targetEntry = path.resolve(process.cwd(), opts.entryPath);
|
|
202
|
+
const relevant = porcelain.filter((line) => {
|
|
203
|
+
// Tolerate any 2-char status (M, A, D, ??, etc.); we just need the path.
|
|
204
|
+
const filePath = line.slice(3).trim();
|
|
205
|
+
return path.resolve(repoRoot, filePath) === targetEntry;
|
|
206
|
+
});
|
|
207
|
+
if (porcelain.length === 0) {
|
|
208
|
+
throw new Error('refusing to open PR: working tree has no changes (did you forget to apply the verdict?)');
|
|
209
|
+
}
|
|
210
|
+
if (porcelain.length !== relevant.length) {
|
|
211
|
+
const offenders = porcelain.filter((l) => !relevant.includes(l)).map((l) => l.slice(3).trim());
|
|
212
|
+
throw new Error(`refusing to open PR: working tree has unrelated changes:\n${offenders.map((o) => ` - ${o}`).join('\n')}\n` +
|
|
213
|
+
'Commit/stash unrelated changes before running --open-pr.');
|
|
214
|
+
}
|
|
215
|
+
const ymd = todayUtcYmd(opts.now);
|
|
216
|
+
const branch = branchNameForEntry(verdict.entry_name, ymd);
|
|
217
|
+
const rendered = renderFreshnessPr(verdict, { mmrJobId: opts.mmrJobId });
|
|
218
|
+
// Branch off main so the PR is against the same base regardless of which
|
|
219
|
+
// local branch the operator was on. `-C` forcefully creates or resets the
|
|
220
|
+
// branch — needed for re-runs on the same date (workflow_dispatch retry
|
|
221
|
+
// after a cron failure), where `-c` would fail because the branch already
|
|
222
|
+
// exists. F-001.
|
|
223
|
+
runOrThrow('git', ['fetch', 'origin', 'main']);
|
|
224
|
+
runOrThrow('git', ['switch', '-C', branch, 'origin/main']);
|
|
225
|
+
// Re-stage the file. After switching branches, the file's working-tree
|
|
226
|
+
// contents are preserved (since the change wasn't committed), but the
|
|
227
|
+
// index gets reset; `git add` re-stages explicitly.
|
|
228
|
+
runOrThrow('git', ['add', '--', opts.entryPath]);
|
|
229
|
+
// Conventional-commits commit. We pass the body via stdin (-F -) so the
|
|
230
|
+
// multi-line body survives shell quoting.
|
|
231
|
+
const commitMsg = `${rendered.title}\n\n${rendered.body}`;
|
|
232
|
+
const commit = spawnSync('git', ['commit', '-F', '-'], { input: commitMsg, encoding: 'utf8' });
|
|
233
|
+
if (commit.status !== 0) {
|
|
234
|
+
throw new Error(`git commit failed (exit ${commit.status})\nstdout: ${commit.stdout}\nstderr: ${commit.stderr}`);
|
|
235
|
+
}
|
|
236
|
+
// Force-push so re-runs on the same date overwrite the prior bot-run
|
|
237
|
+
// branch state instead of erroring (F-002 + F-001 follow-through). This
|
|
238
|
+
// is safe because branches under `knowledge-freshness/*` are bot-owned;
|
|
239
|
+
// human edits live on other branches.
|
|
240
|
+
runOrThrow('git', ['push', '--force-with-lease', '-u', 'origin', branch]);
|
|
241
|
+
// If a PR already exists for this branch, UPDATE it instead of trying to
|
|
242
|
+
// create a new one (F-002). gh pr create errors when a PR is already open
|
|
243
|
+
// for the head ref, which would crash the daily cron on retry.
|
|
244
|
+
const existingPrList = spawnSync('gh', ['pr', 'list', '--head', branch, '--state', 'open', '--json', 'number,url'], { encoding: 'utf8' });
|
|
245
|
+
let prUrl = '';
|
|
246
|
+
if (existingPrList.status === 0) {
|
|
247
|
+
try {
|
|
248
|
+
const parsed = JSON.parse(existingPrList.stdout || '[]');
|
|
249
|
+
if (parsed.length > 0) {
|
|
250
|
+
const existing = parsed[0];
|
|
251
|
+
// Update title + body on the existing PR via `gh pr edit`.
|
|
252
|
+
const editResult = spawnSync('gh', ['pr', 'edit', String(existing.number), '--title', rendered.title, '--body', rendered.body], { encoding: 'utf8' });
|
|
253
|
+
if (editResult.status !== 0) {
|
|
254
|
+
throw new Error(`gh pr edit failed (exit ${editResult.status})\nstdout: ${editResult.stdout}\nstderr: ${editResult.stderr}`);
|
|
255
|
+
}
|
|
256
|
+
prUrl = existing.url;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
throw new Error(`failed to parse gh pr list output: ${err.message}`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (!prUrl) {
|
|
264
|
+
// No existing PR — open a new one. Labels are best-effort and added below.
|
|
265
|
+
const ghArgs = [
|
|
266
|
+
'pr', 'create', '--base', 'main', '--head', branch,
|
|
267
|
+
'--title', rendered.title, '--body', rendered.body,
|
|
268
|
+
];
|
|
269
|
+
const ghResult = spawnSync('gh', ghArgs, { encoding: 'utf8' });
|
|
270
|
+
if (ghResult.status !== 0) {
|
|
271
|
+
throw new Error(`gh pr create failed (exit ${ghResult.status})\nstdout: ${ghResult.stdout}\nstderr: ${ghResult.stderr}`);
|
|
272
|
+
}
|
|
273
|
+
prUrl = (ghResult.stdout ?? '').trim().split('\n').pop() ?? '';
|
|
274
|
+
}
|
|
275
|
+
// Best-effort label attachment. `gh pr edit --add-label` will create
|
|
276
|
+
// the labels in the repo on first use only if they exist; the workflow's
|
|
277
|
+
// first manual dispatch should seed them. We swallow errors so a missing
|
|
278
|
+
// label doesn't fail the PR.
|
|
279
|
+
const labels = ['knowledge-freshness'];
|
|
280
|
+
const volLabel = volatilityLabel(opts.volatility);
|
|
281
|
+
if (volLabel)
|
|
282
|
+
labels.push(volLabel);
|
|
283
|
+
const labelArgs = ['pr', 'edit', prUrl, ...labels.flatMap((l) => ['--add-label', l])];
|
|
284
|
+
const labelResult = spawnSync('gh', labelArgs, { encoding: 'utf8' });
|
|
285
|
+
if (labelResult.status !== 0) {
|
|
286
|
+
process.stderr.write(`warning: failed to attach labels (${labels.join(', ')}): ${labelResult.stderr?.trim()}\n`);
|
|
287
|
+
}
|
|
288
|
+
return { branch, prUrl };
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Extract `volatility` from an entry's frontmatter. We can't import the
|
|
292
|
+
* knowledge-loader here because it pulls in the full assembly stack;
|
|
293
|
+
* a minimal yaml-only read keeps this surface lean.
|
|
294
|
+
*/
|
|
295
|
+
export function readVolatility(entryContent) {
|
|
296
|
+
// F-004 round-4: tolerate optional UTF-8 BOM (U+FEFF) and CRLF line
|
|
297
|
+
// endings. The strict /^---\n.../ regex would silently miss-match a
|
|
298
|
+
// file authored on Windows or with a BOM, leaving the PR without its
|
|
299
|
+
// volatility label. We strip a leading BOM defensively, then match
|
|
300
|
+
// both LF and CRLF line endings via \r?\n.
|
|
301
|
+
const BOM = '';
|
|
302
|
+
const noBom = entryContent.startsWith(BOM) ? entryContent.slice(BOM.length) : entryContent;
|
|
303
|
+
const match = noBom.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
304
|
+
if (!match)
|
|
305
|
+
return undefined;
|
|
306
|
+
const fm = yaml.load(match[1], { schema: yaml.JSON_SCHEMA });
|
|
307
|
+
return fm?.volatility;
|
|
308
|
+
}
|
|
309
|
+
//# sourceMappingURL=audit-apply-pr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-apply-pr.js","sourceRoot":"","sources":["../../src/knowledge-freshness/audit-apply-pr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-apply-pr.test.d.ts","sourceRoot":"","sources":["../../src/knowledge-freshness/audit-apply-pr.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { renderPrTitle, renderPrBody, renderFindingsTable, renderFreshnessPr, branchNameForEntry, sanitizeForBranch, todayUtcYmd, volatilityLabel, readVolatility, } from './audit-apply-pr.js';
|
|
3
|
+
const baseVerdict = {
|
|
4
|
+
entry_name: 'security-owasp',
|
|
5
|
+
audit_date: '2026-05-25',
|
|
6
|
+
model: 'claude-opus-4-7',
|
|
7
|
+
verdict: 'major-drift',
|
|
8
|
+
sources_checked: [
|
|
9
|
+
{
|
|
10
|
+
url: 'https://owasp.org/Top10/',
|
|
11
|
+
retrieved_at: '2026-05-25',
|
|
12
|
+
content_hash: 'sha256:abc123',
|
|
13
|
+
summary: 'OWASP Top 10 landing page',
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
findings: [
|
|
17
|
+
{
|
|
18
|
+
claim_in_entry: 'OWASP Top 10 was last updated in 2021.',
|
|
19
|
+
evidence_url: 'https://owasp.org/Top10/2025/',
|
|
20
|
+
evidence_date: '2026-05-25',
|
|
21
|
+
source_excerpt: 'The 2025 edition adds A11 Software Supply Chain Failures.',
|
|
22
|
+
severity: 'P1',
|
|
23
|
+
drift_kind: 'edition-supersession',
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
proposed_changes: [
|
|
27
|
+
{
|
|
28
|
+
location: '## Summary',
|
|
29
|
+
kind: 'replace',
|
|
30
|
+
rationale: 'Note new 2025 edition',
|
|
31
|
+
new_text: '## Summary\n\n> 2025 edition adds A11.',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
preserve_warnings: ['Keep ## Deep Guidance heading.'],
|
|
35
|
+
};
|
|
36
|
+
describe('renderPrTitle', () => {
|
|
37
|
+
it('uses the conventional-commits chore(knowledge) prefix', () => {
|
|
38
|
+
const title = renderPrTitle(baseVerdict);
|
|
39
|
+
expect(title.startsWith('chore(knowledge): refresh security-owasp against ')).toBe(true);
|
|
40
|
+
expect(title).toContain('https://owasp.org/Top10/');
|
|
41
|
+
});
|
|
42
|
+
it('summarizes multi-source verdicts with "and N other source(s)"', () => {
|
|
43
|
+
const v = {
|
|
44
|
+
...baseVerdict,
|
|
45
|
+
sources_checked: [
|
|
46
|
+
...baseVerdict.sources_checked,
|
|
47
|
+
{ url: 'https://example.com/a', retrieved_at: '2026-05-25', content_hash: 'sha256:1', summary: '' },
|
|
48
|
+
{ url: 'https://example.com/b', retrieved_at: '2026-05-25', content_hash: 'sha256:2', summary: '' },
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
expect(renderPrTitle(v)).toContain('and 2 other source(s)');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe('renderFindingsTable', () => {
|
|
55
|
+
it('renders a markdown table with one row per finding', () => {
|
|
56
|
+
const table = renderFindingsTable(baseVerdict);
|
|
57
|
+
expect(table).toContain('| severity | drift_kind | claim_in_entry | evidence_url |');
|
|
58
|
+
expect(table).toContain('|---|---|---|---|');
|
|
59
|
+
expect(table).toContain('| P1 | edition-supersession |');
|
|
60
|
+
expect(table).toContain('https://owasp.org/Top10/2025/');
|
|
61
|
+
});
|
|
62
|
+
it('escapes pipes and collapses newlines so a stray bar does not break the row', () => {
|
|
63
|
+
const v = {
|
|
64
|
+
...baseVerdict,
|
|
65
|
+
findings: [{
|
|
66
|
+
claim_in_entry: 'has | a pipe and\nnewline',
|
|
67
|
+
evidence_url: 'https://x',
|
|
68
|
+
evidence_date: '2026-05-25',
|
|
69
|
+
source_excerpt: '',
|
|
70
|
+
severity: 'P2',
|
|
71
|
+
drift_kind: 'fact-change',
|
|
72
|
+
}],
|
|
73
|
+
};
|
|
74
|
+
const table = renderFindingsTable(v);
|
|
75
|
+
// Pipe must be escaped; newline must collapse to a space.
|
|
76
|
+
expect(table).toContain('has \\| a pipe and newline');
|
|
77
|
+
// Exactly 3 rows: header + sep + 1 finding (no extra rows from the newline).
|
|
78
|
+
expect(table.split('\n').length).toBe(3);
|
|
79
|
+
});
|
|
80
|
+
it('emits "_No findings._" when the verdict has no findings', () => {
|
|
81
|
+
const v = { ...baseVerdict, findings: [] };
|
|
82
|
+
expect(renderFindingsTable(v)).toBe('_No findings._');
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
describe('renderPrBody', () => {
|
|
86
|
+
it('contains all required sections in order', () => {
|
|
87
|
+
const body = renderPrBody(baseVerdict);
|
|
88
|
+
const sections = ['## Summary', '## Verdict', '## Findings', '## MMR', '## Sources', '## Preserve warnings'];
|
|
89
|
+
let cursor = -1;
|
|
90
|
+
for (const s of sections) {
|
|
91
|
+
const idx = body.indexOf(s);
|
|
92
|
+
expect(idx).toBeGreaterThan(cursor);
|
|
93
|
+
cursor = idx;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
it('includes verdict fields verbatim', () => {
|
|
97
|
+
const body = renderPrBody(baseVerdict);
|
|
98
|
+
expect(body).toContain('- verdict: major-drift');
|
|
99
|
+
expect(body).toContain('- audit_date: 2026-05-25');
|
|
100
|
+
expect(body).toContain('- model: claude-opus-4-7');
|
|
101
|
+
});
|
|
102
|
+
it('shows MMR job ID when supplied, placeholder otherwise', () => {
|
|
103
|
+
expect(renderPrBody(baseVerdict, { mmrJobId: 'job-abc' })).toContain('job_id: job-abc');
|
|
104
|
+
expect(renderPrBody(baseVerdict)).toContain('_Not run inline');
|
|
105
|
+
});
|
|
106
|
+
it('renders source provenance with hash and retrieved date', () => {
|
|
107
|
+
const body = renderPrBody(baseVerdict);
|
|
108
|
+
expect(body).toContain('https://owasp.org/Top10/ (sha256:abc123, retrieved 2026-05-25)');
|
|
109
|
+
});
|
|
110
|
+
it('shows preserve_warnings list when present, "_None._" when empty', () => {
|
|
111
|
+
expect(renderPrBody(baseVerdict)).toContain('- Keep ## Deep Guidance heading.');
|
|
112
|
+
const empty = { ...baseVerdict, preserve_warnings: [] };
|
|
113
|
+
expect(renderPrBody(empty)).toContain('## Preserve warnings\n_None._');
|
|
114
|
+
});
|
|
115
|
+
it('handles a verdict with zero sources_checked without throwing', () => {
|
|
116
|
+
const v = { ...baseVerdict, sources_checked: [] };
|
|
117
|
+
const body = renderPrBody(v);
|
|
118
|
+
expect(body).toContain('_No sources._');
|
|
119
|
+
});
|
|
120
|
+
it('strips ALL JS line terminators from LLM fields (round-7 F-002/F-003/F-004)', () => {
|
|
121
|
+
// Build a verdict whose preserve_warnings contains every JS line
|
|
122
|
+
// terminator followed by BREAKING CHANGE:. The rendered body must NOT
|
|
123
|
+
// contain a start-of-line "BREAKING CHANGE:" — otherwise the
|
|
124
|
+
// version-bump workflow would treat it as a real major-bump footer.
|
|
125
|
+
const v = {
|
|
126
|
+
...baseVerdict,
|
|
127
|
+
preserve_warnings: [
|
|
128
|
+
'before\nBREAKING CHANGE: injected via LF',
|
|
129
|
+
'before\rBREAKING CHANGE: injected via CR',
|
|
130
|
+
'before\r\nBREAKING CHANGE: injected via CRLF',
|
|
131
|
+
'before
BREAKING CHANGE: injected via LS',
|
|
132
|
+
'before
BREAKING CHANGE: injected via PS',
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
const body = renderPrBody(v);
|
|
136
|
+
// No matter which terminator the LLM used, none of them should produce
|
|
137
|
+
// a line whose start is "BREAKING CHANGE:". A multiline-anchor regex
|
|
138
|
+
// confirms the round-2 deriveBumpKind check would now see zero matches.
|
|
139
|
+
expect(/^BREAKING CHANGE:/m.test(body)).toBe(false);
|
|
140
|
+
});
|
|
141
|
+
it('strips line terminators from findings-table cells too', () => {
|
|
142
|
+
const v = {
|
|
143
|
+
...baseVerdict,
|
|
144
|
+
findings: [{
|
|
145
|
+
claim_in_entry: 'old claim\rBREAKING CHANGE: still smuggled',
|
|
146
|
+
evidence_url: 'https://example.org/x',
|
|
147
|
+
evidence_date: '2026-05-25',
|
|
148
|
+
source_excerpt: 'irrelevant',
|
|
149
|
+
severity: 'P1',
|
|
150
|
+
drift_kind: 'wording',
|
|
151
|
+
}],
|
|
152
|
+
};
|
|
153
|
+
const body = renderPrBody(v);
|
|
154
|
+
expect(/^BREAKING CHANGE:/m.test(body)).toBe(false);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
describe('renderFreshnessPr', () => {
|
|
158
|
+
it('returns title, body, and entry_name in one structured payload', () => {
|
|
159
|
+
const out = renderFreshnessPr(baseVerdict, { mmrJobId: 'job-xyz' });
|
|
160
|
+
expect(out.title).toContain('chore(knowledge): refresh security-owasp');
|
|
161
|
+
expect(out.body).toContain('job_id: job-xyz');
|
|
162
|
+
expect(out.entryName).toBe('security-owasp');
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
describe('branchNameForEntry', () => {
|
|
166
|
+
it('uses the knowledge-freshness/<entry>-<date> shape', () => {
|
|
167
|
+
expect(branchNameForEntry('security-owasp', '2026-05-25')).toBe('knowledge-freshness/security-owasp-2026-05-25');
|
|
168
|
+
});
|
|
169
|
+
it('sanitizes whitespace and forbidden characters out of the entry name', () => {
|
|
170
|
+
expect(sanitizeForBranch('a b/c d')).toBe('a-b-c-d');
|
|
171
|
+
expect(sanitizeForBranch('--leading-trailing--')).toBe('leading-trailing');
|
|
172
|
+
expect(() => sanitizeForBranch('/// ')).toThrow(/empty string/);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
describe('todayUtcYmd', () => {
|
|
176
|
+
it('formats UTC date as YYYY-MM-DD with leading zeros', () => {
|
|
177
|
+
expect(todayUtcYmd(new Date('2026-01-05T23:59:59Z'))).toBe('2026-01-05');
|
|
178
|
+
});
|
|
179
|
+
it('uses UTC, not local time (boundary case)', () => {
|
|
180
|
+
// 2026-05-25 23:30 UTC is still 2026-05-25 in UTC regardless of local TZ.
|
|
181
|
+
expect(todayUtcYmd(new Date('2026-05-25T23:30:00Z'))).toBe('2026-05-25');
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
describe('volatilityLabel', () => {
|
|
185
|
+
it('maps known volatility values to labels', () => {
|
|
186
|
+
expect(volatilityLabel('fast-moving')).toBe('volatility:fast-moving');
|
|
187
|
+
expect(volatilityLabel('evolving')).toBe('volatility:evolving');
|
|
188
|
+
expect(volatilityLabel('stable')).toBe('volatility:stable');
|
|
189
|
+
});
|
|
190
|
+
it('returns undefined for unknown values so we do not attach a bogus label', () => {
|
|
191
|
+
expect(volatilityLabel(undefined)).toBeUndefined();
|
|
192
|
+
expect(volatilityLabel('something-else')).toBeUndefined();
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
describe('readVolatility', () => {
|
|
196
|
+
it('parses volatility from a frontmatter block', () => {
|
|
197
|
+
const entry = `---
|
|
198
|
+
name: x
|
|
199
|
+
volatility: fast-moving
|
|
200
|
+
sources: []
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
body
|
|
204
|
+
`;
|
|
205
|
+
expect(readVolatility(entry)).toBe('fast-moving');
|
|
206
|
+
});
|
|
207
|
+
it('returns undefined when there is no frontmatter', () => {
|
|
208
|
+
expect(readVolatility('# no frontmatter')).toBeUndefined();
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
//# sourceMappingURL=audit-apply-pr.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-apply-pr.test.js","sourceRoot":"","sources":["../../src/knowledge-freshness/audit-apply-pr.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EACL,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,qBAAqB,CAAA;AAG5B,MAAM,WAAW,GAAiB;IAChC,UAAU,EAAE,gBAAgB;IAC5B,UAAU,EAAE,YAAY;IACxB,KAAK,EAAE,iBAAiB;IACxB,OAAO,EAAE,aAAa;IACtB,eAAe,EAAE;QACf;YACE,GAAG,EAAE,0BAA0B;YAC/B,YAAY,EAAE,YAAY;YAC1B,YAAY,EAAE,eAAe;YAC7B,OAAO,EAAE,2BAA2B;SACrC;KACF;IACD,QAAQ,EAAE;QACR;YACE,cAAc,EAAE,wCAAwC;YACxD,YAAY,EAAE,+BAA+B;YAC7C,aAAa,EAAE,YAAY;YAC3B,cAAc,EAAE,2DAA2D;YAC3E,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,sBAAsB;SACnC;KACF;IACD,gBAAgB,EAAE;QAChB;YACE,QAAQ,EAAE,YAAY;YACtB,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,uBAAuB;YAClC,QAAQ,EAAE,wCAAwC;SACnD;KACF;IACD,iBAAiB,EAAE,CAAC,gCAAgC,CAAC;CACtD,CAAA;AAED,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,KAAK,GAAG,aAAa,CAAC,WAAW,CAAC,CAAA;QACxC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,mDAAmD,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACxF,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,CAAC,GAAiB;YACtB,GAAG,WAAW;YACd,eAAe,EAAE;gBACf,GAAG,WAAW,CAAC,eAAe;gBAC9B,EAAE,GAAG,EAAE,uBAAuB,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE;gBACnG,EAAE,GAAG,EAAE,uBAAuB,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE;aACpG;SACF,CAAA;QACD,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAA;IAC7D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,KAAK,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAA;QAC9C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,2DAA2D,CAAC,CAAA;QACpF,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAA;QAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAA;QACxD,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAA;IAC1D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACpF,MAAM,CAAC,GAAiB;YACtB,GAAG,WAAW;YACd,QAAQ,EAAE,CAAC;oBACT,cAAc,EAAE,2BAA2B;oBAC3C,YAAY,EAAE,WAAW;oBACzB,aAAa,EAAE,YAAY;oBAC3B,cAAc,EAAE,EAAE;oBAClB,QAAQ,EAAE,IAAI;oBACd,UAAU,EAAE,aAAa;iBAC1B,CAAC;SACH,CAAA;QACD,MAAM,KAAK,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAA;QACpC,0DAA0D;QAC1D,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAA;QACrD,6EAA6E;QAC7E,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,GAAiB,EAAE,GAAG,WAAW,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;QACxD,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,IAAI,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;QACtC,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,sBAAsB,CAAC,CAAA;QAC5G,IAAI,MAAM,GAAG,CAAC,CAAC,CAAA;QACf,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;YACnC,MAAM,GAAG,GAAG,CAAA;QACd,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;QACtC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAA;QAChD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAA;QAClD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAA;IACpD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAA;QACvF,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAA;IAChE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,IAAI,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;QACtC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gEAAgE,CAAC,CAAA;IAC1F,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAA;QAC/E,MAAM,KAAK,GAAiB,EAAE,GAAG,WAAW,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAA;QACrE,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAA;IACxE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,CAAC,GAAiB,EAAE,GAAG,WAAW,EAAE,eAAe,EAAE,EAAE,EAAE,CAAA;QAC/D,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAA;QAC5B,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACpF,iEAAiE;QACjE,sEAAsE;QACtE,6DAA6D;QAC7D,oEAAoE;QACpE,MAAM,CAAC,GAAiB;YACtB,GAAG,WAAW;YACd,iBAAiB,EAAE;gBACjB,0CAA0C;gBAC1C,0CAA0C;gBAC1C,8CAA8C;gBAC9C;iCACyB;gBACzB;iCACyB;aAC1B;SACF,CAAA;QACD,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAA;QAC5B,uEAAuE;QACvE,qEAAqE;QACrE,wEAAwE;QACxE,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,GAAiB;YACtB,GAAG,WAAW;YACd,QAAQ,EAAE,CAAC;oBACT,cAAc,EAAE,4CAA4C;oBAC5D,YAAY,EAAE,uBAAuB;oBACrC,aAAa,EAAE,YAAY;oBAC3B,cAAc,EAAE,YAAY;oBAC5B,QAAQ,EAAE,IAAI;oBACd,UAAU,EAAE,SAAS;iBACtB,CAAC;SACH,CAAA;QACD,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAA;QAC5B,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,GAAG,GAAG,iBAAiB,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAA;QACnE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,0CAA0C,CAAC,CAAA;QACvE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAA;QAC7C,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,CAAC,kBAAkB,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAA;IAClH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACpD,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;QAC1E,MAAM,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;IACjE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IAC1E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,0EAA0E;QAC1E,MAAM,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IAC1E,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;QACrE,MAAM,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;QAC/D,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;IAC7D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,EAAE,CAAA;QAClD,MAAM,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAA;IAC3D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,KAAK,GAAG;;;;;;;CAOjB,CAAA;QACG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAA;IAC5D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AuditVerdict } from './audit-runner.js';
|
|
2
|
+
/** Strip a URL fragment/anchor so verdict sources match frontmatter sources reliably. */
|
|
3
|
+
export declare function normalizeUrl(u: string): string;
|
|
4
|
+
export interface ApplyOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Optional map of normalized-url → fresh sha256 hash, computed deterministically
|
|
7
|
+
* by the caller (typically the CLI wrapper, which re-fetches each
|
|
8
|
+
* `verdict.sources_checked.url` before calling apply). When provided, these
|
|
9
|
+
* hashes are persisted to frontmatter instead of the LLM-claimed
|
|
10
|
+
* `content_hash` (which is not deterministically verifiable). When omitted —
|
|
11
|
+
* e.g. in unit tests — apply falls back to the LLM-claimed hash.
|
|
12
|
+
*/
|
|
13
|
+
trustedHashes?: Map<string, string>;
|
|
14
|
+
}
|
|
15
|
+
export declare function applyVerdictToEntry(original: string, verdict: AuditVerdict, opts?: ApplyOptions): string;
|
|
16
|
+
//# sourceMappingURL=audit-apply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-apply.d.ts","sourceRoot":"","sources":["../../src/knowledge-freshness/audit-apply.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAyBrD,yFAAyF;AACzF,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG9C;AAKD,MAAM,WAAW,YAAY;IAC3B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACpC;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,YAAY,EACrB,IAAI,GAAE,YAAiB,GACtB,MAAM,CAqKR"}
|