kibi-cli 2.1.0 → 2.3.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/dist/cli-operation-loader.d.ts.map +1 -1
- package/dist/cli-operation-loader.js +3 -0
- package/dist/cli-operation-metadata.d.ts +4 -0
- package/dist/cli-operation-metadata.d.ts.map +1 -1
- package/dist/cli-operation-metadata.js +5 -0
- package/dist/cli-protocol.d.ts.map +1 -1
- package/dist/cli-protocol.js +3 -2
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +4 -0
- package/dist/commands/aggregated-checks.d.ts +7 -0
- package/dist/commands/aggregated-checks.d.ts.map +1 -1
- package/dist/commands/aggregated-checks.js +25 -1
- package/dist/commands/check-diff.d.ts +5 -0
- package/dist/commands/check-diff.d.ts.map +1 -0
- package/dist/commands/check-diff.js +62 -0
- package/dist/commands/check-generated.d.ts.map +1 -1
- package/dist/commands/check-generated.js +41 -18
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +231 -86
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +168 -53
- package/dist/commands/github-init.d.ts +1 -1
- package/dist/commands/github-init.d.ts.map +1 -1
- package/dist/commands/github-init.js +10 -3
- package/dist/commands/init-helpers.d.ts +17 -2
- package/dist/commands/init-helpers.d.ts.map +1 -1
- package/dist/commands/init-helpers.js +123 -23
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +110 -15
- package/dist/commands/prove.d.ts.map +1 -1
- package/dist/commands/prove.js +10 -18
- package/dist/commands/sync/cache.d.ts +20 -1
- package/dist/commands/sync/cache.d.ts.map +1 -1
- package/dist/commands/sync/cache.js +51 -2
- package/dist/commands/sync/discovery.d.ts.map +1 -1
- package/dist/commands/sync/discovery.js +1 -1
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +3 -1
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +8 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +11 -3
- package/dist/engine.d.ts +41 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +377 -80
- package/dist/extractors/manifest.d.ts.map +1 -1
- package/dist/extractors/manifest.js +66 -28
- package/dist/extractors/markdown.d.ts +2 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +14 -3
- package/dist/extractors/relationships.d.ts.map +1 -1
- package/dist/extractors/relationships.js +1 -0
- package/dist/extractors/symbols-coordinator.d.ts +7 -0
- package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.js +75 -39
- package/dist/intent-search.d.ts.map +1 -1
- package/dist/intent-search.js +68 -29
- package/dist/operations/bootstrap/generate.d.ts.map +1 -1
- package/dist/operations/bootstrap/generate.js +4 -3
- package/dist/operations/modeling/model-requirement.d.ts +1 -1
- package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
- package/dist/operations/modeling/model-requirement.js +176 -10
- package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-applyplan.js +14 -2
- package/dist/operations/modeling/predicate-inference-1.js +1 -1
- package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-loader.js +24 -0
- package/dist/operations/modeling/predicate-types.d.ts +4 -0
- package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-vocabulary.d.ts +54 -0
- package/dist/operations/modeling/predicate-vocabulary.d.ts.map +1 -0
- package/dist/operations/modeling/predicate-vocabulary.js +169 -0
- package/dist/operations/modeling/requirement-types.d.ts +5 -0
- package/dist/operations/modeling/requirement-types.d.ts.map +1 -1
- package/dist/operations/modeling/vocabulary-alignment.d.ts +60 -0
- package/dist/operations/modeling/vocabulary-alignment.d.ts.map +1 -0
- package/dist/operations/modeling/vocabulary-alignment.js +178 -0
- package/dist/operations/mutation/contradictions.d.ts +3 -0
- package/dist/operations/mutation/contradictions.d.ts.map +1 -1
- package/dist/operations/mutation/contradictions.js +29 -0
- package/dist/operations/mutation/delete.d.ts.map +1 -1
- package/dist/operations/mutation/delete.js +33 -1
- package/dist/operations/mutation/predicate-vocabulary-guard.d.ts +8 -0
- package/dist/operations/mutation/predicate-vocabulary-guard.d.ts.map +1 -0
- package/dist/operations/mutation/predicate-vocabulary-guard.js +64 -0
- package/dist/operations/mutation/relationships.d.ts +1 -1
- package/dist/operations/mutation/relationships.d.ts.map +1 -1
- package/dist/operations/mutation/relationships.js +1 -0
- package/dist/operations/mutation/saga.d.ts +5 -0
- package/dist/operations/mutation/saga.d.ts.map +1 -1
- package/dist/operations/mutation/saga.js +10 -0
- package/dist/operations/mutation/serialization.d.ts.map +1 -1
- package/dist/operations/mutation/serialization.js +2 -0
- package/dist/operations/mutation/source-authoring.d.ts +6 -0
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +213 -52
- package/dist/operations/mutation/strict-fact.d.ts.map +1 -1
- package/dist/operations/mutation/strict-fact.js +5 -0
- package/dist/operations/mutation/types.d.ts +17 -0
- package/dist/operations/mutation/types.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.d.ts +6 -0
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +77 -11
- package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
- package/dist/operations/mutation/validate-upsert.js +24 -1
- package/dist/operations/mutation/validation.d.ts.map +1 -1
- package/dist/operations/mutation/validation.js +16 -3
- package/dist/operations/planning/apply-plan.d.ts.map +1 -1
- package/dist/operations/planning/apply-plan.js +66 -26
- package/dist/operations/planning/compile-intent.d.ts.map +1 -1
- package/dist/operations/planning/compile-intent.js +3 -1
- package/dist/operations/proof/code-scope.d.ts +17 -0
- package/dist/operations/proof/code-scope.d.ts.map +1 -0
- package/dist/operations/proof/code-scope.js +60 -0
- package/dist/operations/proof/ingest-proof.d.ts +4 -2
- package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
- package/dist/operations/proof/ingest-proof.js +208 -74
- package/dist/operations/proof/migrate-legacy-receipts.d.ts.map +1 -1
- package/dist/operations/proof/migrate-legacy-receipts.js +7 -5
- package/dist/operations/proof/prune-receipts.d.ts.map +1 -1
- package/dist/operations/proof/prune-receipts.js +7 -5
- package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analysis-receipt.js +7 -1
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +26 -4
- package/dist/operations/semantic-advisor/clauses.d.ts +1 -0
- package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/clauses.js +7 -1
- package/dist/performance-trace.d.ts +17 -0
- package/dist/performance-trace.d.ts.map +1 -0
- package/dist/performance-trace.js +134 -0
- package/dist/plugins/approved-source-analyzers.d.ts +13 -0
- package/dist/plugins/approved-source-analyzers.d.ts.map +1 -0
- package/dist/plugins/approved-source-analyzers.generated.d.ts +71 -0
- package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -0
- package/dist/plugins/approved-source-analyzers.generated.js +77 -0
- package/dist/plugins/approved-source-analyzers.js +3 -0
- package/dist/plugins/compose-semantic-classifier.d.ts +6 -1
- package/dist/plugins/compose-semantic-classifier.d.ts.map +1 -1
- package/dist/plugins/compose-semantic-classifier.js +8 -3
- package/dist/plugins/compose-vocabulary-alignment.d.ts +23 -0
- package/dist/plugins/compose-vocabulary-alignment.d.ts.map +1 -0
- package/dist/plugins/compose-vocabulary-alignment.js +141 -0
- package/dist/plugins/external-allowlist.d.ts +7 -0
- package/dist/plugins/external-allowlist.d.ts.map +1 -1
- package/dist/plugins/external-allowlist.js +13 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +4 -0
- package/dist/plugins/maintenance-source-analysis.d.ts +14 -0
- package/dist/plugins/maintenance-source-analysis.d.ts.map +1 -0
- package/dist/plugins/maintenance-source-analysis.js +191 -0
- package/dist/plugins/registry.d.ts +3 -1
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +27 -1
- package/dist/plugins/source-analysis-service.d.ts +36 -1
- package/dist/plugins/source-analysis-service.d.ts.map +1 -1
- package/dist/plugins/source-analysis-service.js +184 -27
- package/dist/plugins/source-change-analysis.d.ts +15 -0
- package/dist/plugins/source-change-analysis.d.ts.map +1 -0
- package/dist/plugins/source-change-analysis.js +54 -0
- package/dist/plugins/source-classification.d.ts +41 -0
- package/dist/plugins/source-classification.d.ts.map +1 -0
- package/dist/plugins/source-classification.js +490 -0
- package/dist/prolog/codec.d.ts.map +1 -1
- package/dist/prolog/codec.js +2 -0
- package/dist/prolog/swipl-resolver.d.ts +88 -0
- package/dist/prolog/swipl-resolver.d.ts.map +1 -0
- package/dist/prolog/swipl-resolver.js +446 -0
- package/dist/prolog.d.ts +51 -1
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +145 -15
- package/dist/public/diagnostic-usage.d.ts.map +1 -1
- package/dist/public/diagnostic-usage.js +7 -25
- package/dist/public/impact/analyzer.d.ts.map +1 -1
- package/dist/public/impact/analyzer.js +56 -5
- package/dist/public/impact/diagnostics.d.ts.map +1 -1
- package/dist/public/impact/diagnostics.js +3 -1
- package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
- package/dist/public/impact/full-kb-quality.js +4 -12
- package/dist/public/impact/manifest.d.ts.map +1 -1
- package/dist/public/impact/manifest.js +15 -1
- package/dist/public/impact/source-changes.d.ts.map +1 -1
- package/dist/public/impact/source-changes.js +35 -27
- package/dist/public/impact/types.d.ts +2 -0
- package/dist/public/impact/types.d.ts.map +1 -1
- package/dist/public/operations/catalog.d.ts +80 -7
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/catalog.js +2 -0
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +10 -2
- package/dist/public/operations/check-helpers.d.ts +6 -0
- package/dist/public/operations/check-helpers.d.ts.map +1 -1
- package/dist/public/operations/check-helpers.js +21 -1
- package/dist/public/operations/contracts.d.ts.map +1 -1
- package/dist/public/operations/contracts.js +325 -8
- package/dist/public/operations/discovery-entities.d.ts +42 -2
- package/dist/public/operations/discovery-entities.d.ts.map +1 -1
- package/dist/public/operations/discovery-entities.js +195 -22
- package/dist/public/operations/discovery-executors.d.ts +1 -0
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +75 -46
- package/dist/public/operations/impact-review-preparation.d.ts +14 -0
- package/dist/public/operations/impact-review-preparation.d.ts.map +1 -0
- package/dist/public/operations/impact-review-preparation.js +379 -0
- package/dist/public/operations/index.d.ts +2 -0
- package/dist/public/operations/index.d.ts.map +1 -1
- package/dist/public/operations/index.js +2 -0
- package/dist/public/operations/migration-plan.d.ts +2 -0
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +50 -0
- package/dist/public/operations/node-ports.d.ts.map +1 -1
- package/dist/public/operations/node-ports.js +1 -35
- package/dist/public/operations/predicate-schema-conformance.d.ts +41 -0
- package/dist/public/operations/predicate-schema-conformance.d.ts.map +1 -0
- package/dist/public/operations/predicate-schema-conformance.js +242 -0
- package/dist/public/operations/prolog-json.d.ts.map +1 -1
- package/dist/public/operations/prolog-json.js +9 -3
- package/dist/public/operations/proof-receipt-projection.d.ts +5 -0
- package/dist/public/operations/proof-receipt-projection.d.ts.map +1 -0
- package/dist/public/operations/proof-receipt-projection.js +36 -0
- package/dist/public/operations/result-envelope.d.ts +34 -1
- package/dist/public/operations/result-envelope.d.ts.map +1 -1
- package/dist/public/operations/result-envelope.js +78 -2
- package/dist/public/operations/runtime-types.d.ts +1 -1
- package/dist/public/operations/runtime-types.d.ts.map +1 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
- package/dist/public/operations/specs/check-rules.generated.js +8 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/discovery.d.ts +7 -1
- package/dist/public/operations/specs/discovery.d.ts.map +1 -1
- package/dist/public/operations/specs/discovery.js +7 -1
- package/dist/public/operations/specs/impact-review-preparation.d.ts +47 -0
- package/dist/public/operations/specs/impact-review-preparation.d.ts.map +1 -0
- package/dist/public/operations/specs/impact-review-preparation.js +43 -0
- package/dist/public/operations/specs/mutation-schemas.d.ts +27 -4
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +21 -3
- package/dist/public/operations/specs/reporting.d.ts +8 -0
- package/dist/public/operations/specs/reporting.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.js +46 -15
- package/dist/public/operations/specs/upsert.d.ts +28 -5
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/operations/specs/upsert.js +1 -1
- package/dist/public/operations/symbol-repair-plan.d.ts.map +1 -1
- package/dist/public/operations/symbol-repair-plan.js +8 -3
- package/dist/public/operations/types.d.ts +1 -1
- package/dist/public/operations/types.d.ts.map +1 -1
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +22 -0
- package/dist/public/schemas/relationship.d.ts.map +1 -1
- package/dist/public/schemas/relationship.js +1 -0
- package/dist/public/skills/kibi-usage/SKILL.md +7 -3
- package/dist/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
- package/dist/public/skills/kibi-usage/resources/operation-access.md +1 -0
- package/dist/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
- package/dist/public/skills/kibi-usage/resources/source-authoring.md +36 -0
- package/dist/public/skills/kibi-usage/resources/workflows.md +52 -1
- package/dist/public/telemetry-acceptance.d.ts.map +1 -1
- package/dist/public/telemetry-acceptance.js +21 -5
- package/dist/relationships/shards.d.ts +6 -0
- package/dist/relationships/shards.d.ts.map +1 -1
- package/dist/relationships/shards.js +26 -19
- package/dist/schemas/entity.schema.json +32 -0
- package/dist/traceability/analysis-gate.d.ts +39 -0
- package/dist/traceability/analysis-gate.d.ts.map +1 -0
- package/dist/traceability/analysis-gate.js +51 -0
- package/dist/traceability/git-change-snapshot.d.ts +27 -0
- package/dist/traceability/git-change-snapshot.d.ts.map +1 -0
- package/dist/traceability/git-change-snapshot.js +411 -0
- package/dist/traceability/git-staged.d.ts +5 -1
- package/dist/traceability/git-staged.d.ts.map +1 -1
- package/dist/traceability/git-staged.js +16 -11
- package/dist/traceability/impact-evaluator.d.ts +54 -0
- package/dist/traceability/impact-evaluator.d.ts.map +1 -0
- package/dist/traceability/impact-evaluator.js +270 -0
- package/dist/traceability/impact-git-tree.d.ts +12 -0
- package/dist/traceability/impact-git-tree.d.ts.map +1 -0
- package/dist/traceability/impact-git-tree.js +46 -0
- package/dist/traceability/impact-knowledge.d.ts +16 -0
- package/dist/traceability/impact-knowledge.d.ts.map +1 -0
- package/dist/traceability/impact-knowledge.js +165 -0
- package/dist/traceability/impact-policy.d.ts +15 -0
- package/dist/traceability/impact-policy.d.ts.map +1 -0
- package/dist/traceability/impact-policy.js +48 -0
- package/dist/traceability/impact-policy.v1.schema.json +48 -0
- package/dist/traceability/impact-pr-diff.d.ts +5 -0
- package/dist/traceability/impact-pr-diff.d.ts.map +1 -0
- package/dist/traceability/impact-pr-diff.js +83 -0
- package/dist/traceability/impact-record-validation.d.ts +9 -0
- package/dist/traceability/impact-record-validation.d.ts.map +1 -0
- package/dist/traceability/impact-record-validation.js +113 -0
- package/dist/traceability/impact-review.d.ts +148 -0
- package/dist/traceability/impact-review.d.ts.map +1 -0
- package/dist/traceability/impact-review.js +494 -0
- package/dist/traceability/impact-review.schema.json +365 -0
- package/dist/traceability/impact-side-evidence.d.ts +13 -0
- package/dist/traceability/impact-side-evidence.d.ts.map +1 -0
- package/dist/traceability/impact-side-evidence.js +240 -0
- package/dist/traceability/reviewed-coordinate-refresh.d.ts +10 -0
- package/dist/traceability/reviewed-coordinate-refresh.d.ts.map +1 -0
- package/dist/traceability/reviewed-coordinate-refresh.js +49 -0
- package/dist/traceability/snapshot-knowledge.d.ts +4 -0
- package/dist/traceability/snapshot-knowledge.d.ts.map +1 -0
- package/dist/traceability/snapshot-knowledge.js +98 -0
- package/dist/traceability/staged-diagnostics.d.ts +1 -1
- package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
- package/dist/traceability/staged-entity-id-style.d.ts +12 -0
- package/dist/traceability/staged-entity-id-style.d.ts.map +1 -0
- package/dist/traceability/staged-entity-id-style.js +68 -0
- package/dist/traceability/staged-file-coverage.d.ts +23 -0
- package/dist/traceability/staged-file-coverage.d.ts.map +1 -1
- package/dist/traceability/staged-impact-contract.d.ts.map +1 -1
- package/dist/traceability/staged-impact-contract.js +2 -16
- package/dist/traceability/staged-symbols-manifest.d.ts +4 -0
- package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
- package/dist/traceability/staged-symbols-manifest.js +17 -6
- package/dist/traceability/symbol-extract.d.ts +3 -5
- package/dist/traceability/symbol-extract.d.ts.map +1 -1
- package/dist/traceability/symbol-extract.js +49 -34
- package/dist/traceability/temp-kb.d.ts +1 -1
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +57 -13
- package/dist/traceability/trusted-pr-event.d.ts +13 -0
- package/dist/traceability/trusted-pr-event.d.ts.map +1 -0
- package/dist/traceability/trusted-pr-event.js +105 -0
- package/dist/traceability/validate.js +1 -1
- package/dist/types/entities.d.ts +2 -0
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/types/relationships.d.ts +1 -1
- package/dist/types/relationships.d.ts.map +1 -1
- package/dist/utils/canonical-path.d.ts +3 -0
- package/dist/utils/canonical-path.d.ts.map +1 -0
- package/dist/utils/canonical-path.js +33 -0
- package/dist/utils/entity-id-style.d.ts +27 -0
- package/dist/utils/entity-id-style.d.ts.map +1 -0
- package/dist/utils/entity-id-style.js +81 -0
- package/dist/utils/git-repository-context.d.ts +50 -0
- package/dist/utils/git-repository-context.d.ts.map +1 -0
- package/dist/utils/git-repository-context.js +259 -0
- package/dist/utils/rule-registry.d.ts +5 -0
- package/dist/utils/rule-registry.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.d.ts +37 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +44 -0
- package/dist/utils/strict-modeling.d.ts +7 -0
- package/dist/utils/strict-modeling.d.ts.map +1 -1
- package/dist/utils/strict-modeling.js +11 -0
- package/package.json +14 -5
- package/schema/entities.pl +60 -1
- package/schema/relationships.pl +17 -4
- package/schema/validation.pl +118 -20
- package/src/public/diagnostic-usage.ts +16 -24
- package/src/public/impact/analyzer.ts +88 -5
- package/src/public/impact/diagnostics.ts +7 -5
- package/src/public/impact/full-kb-quality.ts +4 -16
- package/src/public/impact/manifest.ts +14 -1
- package/src/public/impact/source-changes.ts +39 -34
- package/src/public/impact/types.ts +5 -0
- package/src/public/operations/catalog.ts +2 -0
- package/src/public/operations/check-executor.ts +12 -1
- package/src/public/operations/check-helpers.ts +27 -1
- package/src/public/operations/contracts.ts +404 -9
- package/src/public/operations/discovery-entities.ts +292 -23
- package/src/public/operations/discovery-executors.ts +91 -55
- package/src/public/operations/impact-review-preparation.ts +548 -0
- package/src/public/operations/index.ts +2 -0
- package/src/public/operations/migration-plan.ts +57 -0
- package/src/public/operations/node-ports.ts +1 -39
- package/src/public/operations/predicate-schema-conformance.ts +362 -0
- package/src/public/operations/prolog-json.ts +9 -3
- package/src/public/operations/proof-receipt-projection.ts +39 -0
- package/src/public/operations/result-envelope.ts +114 -2
- package/src/public/operations/runtime-types.ts +1 -1
- package/src/public/operations/specs/check-rules.generated.ts +8 -1
- package/src/public/operations/specs/discovery.ts +8 -1
- package/src/public/operations/specs/impact-review-preparation.ts +46 -0
- package/src/public/operations/specs/mutation-schemas.ts +23 -3
- package/src/public/operations/specs/reporting.ts +69 -22
- package/src/public/operations/specs/upsert.ts +1 -1
- package/src/public/operations/symbol-repair-plan.ts +13 -3
- package/src/public/operations/types.ts +1 -0
- package/src/public/schemas/entity.ts +22 -0
- package/src/public/schemas/relationship.ts +1 -0
- package/src/public/skills/kibi-usage/SKILL.md +7 -3
- package/src/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
- package/src/public/skills/kibi-usage/resources/operation-access.md +1 -0
- package/src/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
- package/src/public/skills/kibi-usage/resources/source-authoring.md +36 -0
- package/src/public/skills/kibi-usage/resources/workflows.md +52 -1
- package/src/public/telemetry-acceptance.ts +37 -6
- package/src/schemas/entity.schema.json +32 -0
- package/src/schemas/relationship.schema.json +1 -0
- package/src/traceability/impact-policy.v1.schema.json +48 -0
- package/src/traceability/impact-review.schema.json +365 -0
- package/templates/github/kibi-badge.yml +0 -4
- package/templates/github/kibi-report.yml +0 -4
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
2
|
+
import { isEntityLanePath, isSymbolsManifestPath } from "../utils/kb-paths.js";
|
|
3
|
+
const GIT_EXEC_MAX_BUFFER = 64 * 1024 * 1024;
|
|
4
|
+
function runGit(root, args) {
|
|
5
|
+
try {
|
|
6
|
+
return execFileSync("git", [...args], {
|
|
7
|
+
cwd: root,
|
|
8
|
+
encoding: "buffer",
|
|
9
|
+
maxBuffer: GIT_EXEC_MAX_BUFFER,
|
|
10
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
15
|
+
throw new Error(`git command failed: git ${args.join(" ")} -> ${detail}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function gitText(root, args) {
|
|
19
|
+
return runGit(root, args).toString("utf8").trim();
|
|
20
|
+
}
|
|
21
|
+
function readBlobs(root, oids) {
|
|
22
|
+
const unique = [...new Set(oids)];
|
|
23
|
+
if (unique.some((oid) => !/^[a-f0-9]{40,64}$/.test(oid)))
|
|
24
|
+
throw new Error("Invalid snapshot object ID");
|
|
25
|
+
const result = new Map();
|
|
26
|
+
if (unique.length === 0)
|
|
27
|
+
return result;
|
|
28
|
+
const output = execFileSync("git", ["cat-file", "--batch"], {
|
|
29
|
+
cwd: root,
|
|
30
|
+
input: `${unique.join("\n")}\n`,
|
|
31
|
+
maxBuffer: GIT_EXEC_MAX_BUFFER,
|
|
32
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
33
|
+
});
|
|
34
|
+
let offset = 0;
|
|
35
|
+
for (const oid of unique) {
|
|
36
|
+
const newline = output.indexOf(10, offset);
|
|
37
|
+
const header = output
|
|
38
|
+
.subarray(offset, newline)
|
|
39
|
+
.toString("ascii")
|
|
40
|
+
.split(" ");
|
|
41
|
+
const size = Number(header[2]);
|
|
42
|
+
if (newline < 0 ||
|
|
43
|
+
header[0] !== oid ||
|
|
44
|
+
header[1] !== "blob" ||
|
|
45
|
+
!Number.isSafeInteger(size) ||
|
|
46
|
+
size < 0 ||
|
|
47
|
+
newline + 1 + size >= output.length)
|
|
48
|
+
throw new Error(`Invalid snapshot blob response: ${oid}`);
|
|
49
|
+
const start = newline + 1;
|
|
50
|
+
if (output[start + size] !== 10)
|
|
51
|
+
throw new Error(`Invalid snapshot blob delimiter: ${oid}`);
|
|
52
|
+
result.set(oid, output.subarray(start, start + size));
|
|
53
|
+
offset = start + size + 1;
|
|
54
|
+
}
|
|
55
|
+
if (offset !== output.length)
|
|
56
|
+
throw new Error("Unexpected trailing snapshot blob data");
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
function resolveHeadCommit(root) {
|
|
60
|
+
try {
|
|
61
|
+
return gitText(root, ["rev-parse", "--verify", "HEAD^{commit}"]);
|
|
62
|
+
}
|
|
63
|
+
catch (headError) {
|
|
64
|
+
const ref = gitText(root, ["symbolic-ref", "-q", "HEAD"]);
|
|
65
|
+
const presence = spawnSync("git", ["show-ref", "--verify", "--quiet", ref], { cwd: root, stdio: "ignore" });
|
|
66
|
+
// Only a missing ref is unborn. A present ref pointing to a missing or
|
|
67
|
+
// non-commit object is corruption, not an empty repository.
|
|
68
|
+
if (presence.status === 1)
|
|
69
|
+
return null;
|
|
70
|
+
throw headError;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function emptyTreeOid(root) {
|
|
74
|
+
return gitText(root, ["hash-object", "-t", "tree", "--stdin"]);
|
|
75
|
+
}
|
|
76
|
+
function treeForCommit(root, commit) {
|
|
77
|
+
return commit
|
|
78
|
+
? gitText(root, ["rev-parse", "--verify", `${commit}^{tree}`])
|
|
79
|
+
: emptyTreeOid(root);
|
|
80
|
+
}
|
|
81
|
+
function parseNameStatus(input) {
|
|
82
|
+
const entries = input.toString("utf8").split("\0").filter(Boolean);
|
|
83
|
+
const rows = [];
|
|
84
|
+
for (let index = 0; index < entries.length;) {
|
|
85
|
+
const token = entries[index] ?? "";
|
|
86
|
+
const tab = token.indexOf("\t");
|
|
87
|
+
const statusToken = tab >= 0 ? token.slice(0, tab) : token;
|
|
88
|
+
const inlinePath = tab >= 0 ? token.slice(tab + 1) : undefined;
|
|
89
|
+
const status = (statusToken[0] ?? "M");
|
|
90
|
+
const renamed = status === "R" || status === "C";
|
|
91
|
+
const firstPath = inlinePath ?? entries[index + 1] ?? "";
|
|
92
|
+
const oldPath = renamed ? firstPath : undefined;
|
|
93
|
+
const path = renamed ? (entries[index + 2] ?? "") : (firstPath ?? "");
|
|
94
|
+
rows.push({ status, ...(oldPath !== undefined ? { oldPath } : {}), path });
|
|
95
|
+
index += inlinePath !== undefined ? 1 : renamed ? 3 : 2;
|
|
96
|
+
}
|
|
97
|
+
return rows;
|
|
98
|
+
}
|
|
99
|
+
function literalPathspec(path) {
|
|
100
|
+
return `:(literal)${path}`;
|
|
101
|
+
}
|
|
102
|
+
function readTreeEntry(root, tree, path) {
|
|
103
|
+
const output = runGit(root, [
|
|
104
|
+
"ls-tree",
|
|
105
|
+
"-r",
|
|
106
|
+
"-z",
|
|
107
|
+
tree,
|
|
108
|
+
"--",
|
|
109
|
+
literalPathspec(path),
|
|
110
|
+
]);
|
|
111
|
+
const first = output.toString("utf8").split("\0")[0];
|
|
112
|
+
if (!first)
|
|
113
|
+
return undefined;
|
|
114
|
+
const tab = first.indexOf("\t");
|
|
115
|
+
if (tab < 0)
|
|
116
|
+
return undefined;
|
|
117
|
+
const [mode, type, oid] = first.slice(0, tab).split(" ");
|
|
118
|
+
if (!mode || !type || !oid)
|
|
119
|
+
return undefined;
|
|
120
|
+
return { mode, type, oid };
|
|
121
|
+
}
|
|
122
|
+
function readBlob(root, entry) {
|
|
123
|
+
if (!entry || entry.type !== "blob")
|
|
124
|
+
return undefined;
|
|
125
|
+
return runGit(root, ["cat-file", "blob", entry.oid]);
|
|
126
|
+
}
|
|
127
|
+
function decodeText(buffer) {
|
|
128
|
+
if (buffer.includes(0))
|
|
129
|
+
return { skipReason: "binary" };
|
|
130
|
+
try {
|
|
131
|
+
return {
|
|
132
|
+
content: new TextDecoder("utf-8", { fatal: true }).decode(buffer),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return { skipReason: "unsupported_encoding" };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function hasSupportedExt(path) {
|
|
140
|
+
return /\.(?:ts|tsx|js|jsx|mts|cts|mjs|cjs)$/.test(path);
|
|
141
|
+
}
|
|
142
|
+
function isMetadataPath(path) {
|
|
143
|
+
const normalized = path.replaceAll("\\", "/");
|
|
144
|
+
const relationshipShard = normalized.startsWith(".kb/relationships/") &&
|
|
145
|
+
(normalized.endsWith(".yaml") || normalized.endsWith(".yml"));
|
|
146
|
+
return ((normalized.endsWith(".md") && isEntityLanePath(normalized)) ||
|
|
147
|
+
relationshipShard ||
|
|
148
|
+
normalized === ".kb/manifest.json" ||
|
|
149
|
+
normalized === ".kb/symbols.yaml" ||
|
|
150
|
+
normalized === ".kb/symbols.yml" ||
|
|
151
|
+
normalized === ".kb/symbol-coordinates.yaml" ||
|
|
152
|
+
isSymbolsManifestPath(normalized));
|
|
153
|
+
}
|
|
154
|
+
function analysisFor(path, deleted) {
|
|
155
|
+
if (deleted)
|
|
156
|
+
return "file";
|
|
157
|
+
if (hasSupportedExt(path))
|
|
158
|
+
return "symbol";
|
|
159
|
+
if (isMetadataPath(path))
|
|
160
|
+
return "metadata";
|
|
161
|
+
return "file";
|
|
162
|
+
}
|
|
163
|
+
function parseHunkSides(diffText) {
|
|
164
|
+
const oldHunkRanges = [];
|
|
165
|
+
const hunkRanges = [];
|
|
166
|
+
const regex = /^@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@/gm;
|
|
167
|
+
for (const match of diffText.matchAll(regex)) {
|
|
168
|
+
const oldStart = Number.parseInt(match[1] ?? "0", 10);
|
|
169
|
+
const oldCount = match[2] ? Number.parseInt(match[2], 10) : 1;
|
|
170
|
+
const newStart = Number.parseInt(match[3] ?? "0", 10);
|
|
171
|
+
const newCount = match[4] ? Number.parseInt(match[4], 10) : 1;
|
|
172
|
+
if (oldCount > 0) {
|
|
173
|
+
oldHunkRanges.push({ start: oldStart, end: oldStart + oldCount - 1 });
|
|
174
|
+
}
|
|
175
|
+
if (newCount > 0) {
|
|
176
|
+
hunkRanges.push({ start: newStart, end: newStart + newCount - 1 });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return { oldHunkRanges, hunkRanges };
|
|
180
|
+
}
|
|
181
|
+
function normalizeRanges(ranges, content) {
|
|
182
|
+
const lineCount = Math.max(1, (content ?? "").split(/\r?\n/).length);
|
|
183
|
+
for (const range of ranges) {
|
|
184
|
+
if (range.end === Number.MAX_SAFE_INTEGER)
|
|
185
|
+
range.end = lineCount;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function diffForPath(root, baseTree, headTree, entry) {
|
|
189
|
+
const paths = new Set([entry.oldPath, entry.path].filter((path) => path !== undefined));
|
|
190
|
+
return runGit(root, [
|
|
191
|
+
"diff",
|
|
192
|
+
"--no-ext-diff",
|
|
193
|
+
"--no-color",
|
|
194
|
+
"-U0",
|
|
195
|
+
"-M",
|
|
196
|
+
"-C",
|
|
197
|
+
"--find-copies-harder",
|
|
198
|
+
baseTree,
|
|
199
|
+
headTree,
|
|
200
|
+
"--",
|
|
201
|
+
...[...paths].map(literalPathspec),
|
|
202
|
+
]).toString("utf8");
|
|
203
|
+
}
|
|
204
|
+
function skipReasonForMode(mode) {
|
|
205
|
+
if (mode === "120000")
|
|
206
|
+
return "symlink";
|
|
207
|
+
if (mode === "160000")
|
|
208
|
+
return "submodule";
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
function buildInventory(root, baseTree, headTree) {
|
|
212
|
+
const rows = parseNameStatus(runGit(root, [
|
|
213
|
+
"diff",
|
|
214
|
+
"--name-status",
|
|
215
|
+
"-z",
|
|
216
|
+
"-M",
|
|
217
|
+
"-C",
|
|
218
|
+
"--find-copies-harder",
|
|
219
|
+
"--diff-filter=ACMRTD",
|
|
220
|
+
baseTree,
|
|
221
|
+
headTree,
|
|
222
|
+
]));
|
|
223
|
+
return rows.map((row) => {
|
|
224
|
+
const previousPath = row.oldPath ?? row.path;
|
|
225
|
+
const oldEntry = readTreeEntry(root, baseTree, previousPath);
|
|
226
|
+
const newEntry = readTreeEntry(root, headTree, row.path);
|
|
227
|
+
const oldBlob = readBlob(root, oldEntry);
|
|
228
|
+
const newBlob = readBlob(root, newEntry);
|
|
229
|
+
const oldDecoded = oldBlob ? decodeText(oldBlob) : undefined;
|
|
230
|
+
const newDecoded = newBlob ? decodeText(newBlob) : undefined;
|
|
231
|
+
const diffText = diffForPath(root, baseTree, headTree, row);
|
|
232
|
+
const { oldHunkRanges, hunkRanges } = parseHunkSides(diffText);
|
|
233
|
+
const oldContent = oldDecoded && "content" in oldDecoded ? oldDecoded.content : undefined;
|
|
234
|
+
const newContent = newDecoded && "content" in newDecoded ? newDecoded.content : undefined;
|
|
235
|
+
const oldIsPresent = oldEntry !== undefined;
|
|
236
|
+
const newIsPresent = newEntry !== undefined;
|
|
237
|
+
if (!oldIsPresent && newIsPresent && hunkRanges.length === 0) {
|
|
238
|
+
hunkRanges.push({ start: 1, end: Number.MAX_SAFE_INTEGER });
|
|
239
|
+
}
|
|
240
|
+
if (oldIsPresent && !newIsPresent && oldHunkRanges.length === 0) {
|
|
241
|
+
oldHunkRanges.push({ start: 1, end: Number.MAX_SAFE_INTEGER });
|
|
242
|
+
}
|
|
243
|
+
normalizeRanges(hunkRanges, newContent);
|
|
244
|
+
normalizeRanges(oldHunkRanges, oldContent);
|
|
245
|
+
const gitMode = newEntry?.mode ?? oldEntry?.mode;
|
|
246
|
+
const previousMode = oldEntry?.mode;
|
|
247
|
+
const modeSkip = skipReasonForMode(newEntry?.mode ?? (!newIsPresent ? oldEntry?.mode : undefined));
|
|
248
|
+
const decodeSkip = (newDecoded && "skipReason" in newDecoded
|
|
249
|
+
? newDecoded.skipReason
|
|
250
|
+
: undefined) ??
|
|
251
|
+
(oldDecoded && "skipReason" in oldDecoded
|
|
252
|
+
? oldDecoded.skipReason
|
|
253
|
+
: undefined);
|
|
254
|
+
const skipReason = modeSkip ?? decodeSkip;
|
|
255
|
+
const pathFields = {
|
|
256
|
+
...(row.status === "R" && row.oldPath !== undefined
|
|
257
|
+
? { oldPath: row.oldPath }
|
|
258
|
+
: {}),
|
|
259
|
+
...(row.status === "C" && row.oldPath !== undefined
|
|
260
|
+
? { copyFromPath: row.oldPath }
|
|
261
|
+
: {}),
|
|
262
|
+
};
|
|
263
|
+
if (skipReason) {
|
|
264
|
+
return {
|
|
265
|
+
path: row.path,
|
|
266
|
+
status: row.status,
|
|
267
|
+
...pathFields,
|
|
268
|
+
hunkRanges,
|
|
269
|
+
oldHunkRanges,
|
|
270
|
+
diffText,
|
|
271
|
+
...(gitMode !== undefined ? { gitMode } : {}),
|
|
272
|
+
...(previousMode !== undefined ? { previousMode } : {}),
|
|
273
|
+
...(oldContent !== undefined ? { previousContent: oldContent } : {}),
|
|
274
|
+
analysisDepth: "none",
|
|
275
|
+
disposition: "skipped",
|
|
276
|
+
skipReason,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
const deleted = !newIsPresent;
|
|
280
|
+
const analysisDepth = analysisFor(row.path, deleted);
|
|
281
|
+
const disposition = analysisDepth === "file" ? "advisory" : "checked";
|
|
282
|
+
return {
|
|
283
|
+
path: row.path,
|
|
284
|
+
status: row.status,
|
|
285
|
+
...pathFields,
|
|
286
|
+
hunkRanges,
|
|
287
|
+
oldHunkRanges,
|
|
288
|
+
diffText,
|
|
289
|
+
...(newContent !== undefined ? { content: newContent } : {}),
|
|
290
|
+
...(oldContent !== undefined ? { previousContent: oldContent } : {}),
|
|
291
|
+
...(gitMode !== undefined ? { gitMode } : {}),
|
|
292
|
+
...(previousMode !== undefined ? { previousMode } : {}),
|
|
293
|
+
analysisDepth,
|
|
294
|
+
disposition,
|
|
295
|
+
};
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
function translateReadGit(root, args, baseTree, headTree, baseCommit) {
|
|
299
|
+
if (args[0] === "diff" && args.includes("--cached")) {
|
|
300
|
+
const translated = args.filter((arg) => arg !== "--cached");
|
|
301
|
+
const filterIndex = translated.findIndex((arg) => arg.startsWith("--diff-filter="));
|
|
302
|
+
if (filterIndex >= 0)
|
|
303
|
+
translated[filterIndex] = "--diff-filter=ACMRTD";
|
|
304
|
+
const separator = translated.indexOf("--");
|
|
305
|
+
const insertion = separator < 0 ? translated.length : separator;
|
|
306
|
+
translated.splice(insertion, 0, baseTree, headTree);
|
|
307
|
+
return runGit(root, translated);
|
|
308
|
+
}
|
|
309
|
+
if (args[0] === "ls-files" && args.includes("--stage")) {
|
|
310
|
+
const separator = args.indexOf("--");
|
|
311
|
+
const pathArgs = separator >= 0 ? args.slice(separator + 1) : [];
|
|
312
|
+
const output = runGit(root, [
|
|
313
|
+
"ls-tree",
|
|
314
|
+
"-r",
|
|
315
|
+
"-z",
|
|
316
|
+
headTree,
|
|
317
|
+
...(pathArgs.length ? ["--", ...pathArgs] : []),
|
|
318
|
+
]);
|
|
319
|
+
const rows = output
|
|
320
|
+
.toString("utf8")
|
|
321
|
+
.split("\0")
|
|
322
|
+
.filter(Boolean)
|
|
323
|
+
.map((row) => {
|
|
324
|
+
const tab = row.indexOf("\t");
|
|
325
|
+
if (tab < 0)
|
|
326
|
+
return row;
|
|
327
|
+
const [mode, _type, oid] = row.slice(0, tab).split(" ");
|
|
328
|
+
return `${mode ?? ""} ${oid ?? ""} 0${row.slice(tab)}`;
|
|
329
|
+
});
|
|
330
|
+
return Buffer.from(rows.length ? `${rows.join("\0")}\0` : "");
|
|
331
|
+
}
|
|
332
|
+
if (args[0] === "ls-tree" && args.includes("HEAD")) {
|
|
333
|
+
return runGit(root, args.map((arg) => (arg === "HEAD" ? baseTree : arg)));
|
|
334
|
+
}
|
|
335
|
+
if (args[0] === "rev-parse" && args.some((arg) => arg.startsWith("HEAD"))) {
|
|
336
|
+
const revision = args.find((arg) => arg.startsWith("HEAD")) ?? "HEAD";
|
|
337
|
+
if (revision === "HEAD^{tree}")
|
|
338
|
+
return Buffer.from(`${baseTree}\n`);
|
|
339
|
+
if (revision === "HEAD" || revision === "HEAD^{commit}") {
|
|
340
|
+
if (!baseCommit) {
|
|
341
|
+
throw new Error("HEAD does not resolve to a commit in this snapshot");
|
|
342
|
+
}
|
|
343
|
+
return Buffer.from(`${baseCommit}\n`);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (args[0] === "show") {
|
|
347
|
+
const spec = args[1] ?? "";
|
|
348
|
+
if (spec.startsWith(":")) {
|
|
349
|
+
return runGit(root, ["show", `${headTree}:${spec.slice(1)}`]);
|
|
350
|
+
}
|
|
351
|
+
if (spec.startsWith("HEAD:")) {
|
|
352
|
+
return runGit(root, [
|
|
353
|
+
"show",
|
|
354
|
+
`${baseTree}:${spec.slice("HEAD:".length)}`,
|
|
355
|
+
]);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return runGit(root, args);
|
|
359
|
+
}
|
|
360
|
+
function snapshotFromTrees(root, baseTree, headTree, headCommit, readGit, assertUnchanged) {
|
|
361
|
+
return {
|
|
362
|
+
baseTree,
|
|
363
|
+
headTree,
|
|
364
|
+
headCommit,
|
|
365
|
+
readGit,
|
|
366
|
+
readBlobs: (oids) => readBlobs(root, oids),
|
|
367
|
+
assertUnchanged,
|
|
368
|
+
inventory: buildInventory(root, baseTree, headTree),
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
/** Capture one immutable tree from the index and inventory only Git objects. */
|
|
372
|
+
// implements REQ-014
|
|
373
|
+
export function captureStagedSnapshot(workspaceRoot) {
|
|
374
|
+
const headCommit = resolveHeadCommit(workspaceRoot);
|
|
375
|
+
const baseTree = treeForCommit(workspaceRoot, headCommit);
|
|
376
|
+
const headTree = gitText(workspaceRoot, ["write-tree"]);
|
|
377
|
+
const readGit = (args) => translateReadGit(workspaceRoot, args, baseTree, headTree, headCommit);
|
|
378
|
+
const assertUnchanged = () => {
|
|
379
|
+
const currentHead = resolveHeadCommit(workspaceRoot);
|
|
380
|
+
const currentIndexTree = gitText(workspaceRoot, ["write-tree"]);
|
|
381
|
+
if (currentHead !== headCommit || currentIndexTree !== headTree) {
|
|
382
|
+
throw new Error("Git index or HEAD changed during staged analysis; retry the operation");
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
return snapshotFromTrees(workspaceRoot, baseTree, headTree, headCommit, readGit, assertUnchanged);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Capture changes between explicit revisions. The caller chooses `base`; for
|
|
389
|
+
* merge-impact analysis this is commonly the merge base computed with
|
|
390
|
+
* `git merge-base target head`. This helper resolves each input once and does
|
|
391
|
+
* not silently choose a merge base of its own.
|
|
392
|
+
*/
|
|
393
|
+
// implements REQ-014
|
|
394
|
+
export function captureDiffSnapshot(workspaceRoot, base, head) {
|
|
395
|
+
const baseCommit = gitText(workspaceRoot, [
|
|
396
|
+
"rev-parse",
|
|
397
|
+
"--verify",
|
|
398
|
+
"--end-of-options",
|
|
399
|
+
`${base}^{commit}`,
|
|
400
|
+
]);
|
|
401
|
+
const headCommit = gitText(workspaceRoot, [
|
|
402
|
+
"rev-parse",
|
|
403
|
+
"--verify",
|
|
404
|
+
"--end-of-options",
|
|
405
|
+
`${head}^{commit}`,
|
|
406
|
+
]);
|
|
407
|
+
const baseTree = treeForCommit(workspaceRoot, baseCommit);
|
|
408
|
+
const headTree = treeForCommit(workspaceRoot, headCommit);
|
|
409
|
+
const readGit = (args) => translateReadGit(workspaceRoot, args, baseTree, headTree, baseCommit);
|
|
410
|
+
return snapshotFromTrees(workspaceRoot, baseTree, headTree, baseCommit, readGit, () => undefined);
|
|
411
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type Status = "A" | "M" | "R" | "D";
|
|
1
|
+
export type Status = "A" | "M" | "R" | "C" | "T" | "D";
|
|
2
2
|
export interface HunkRange {
|
|
3
3
|
start: number;
|
|
4
4
|
end: number;
|
|
@@ -16,9 +16,13 @@ export type StagedDisposition = "checked" | "advisory" | "skipped";
|
|
|
16
16
|
export type StagedSkipReason = "binary" | "unsupported_encoding" | "symlink" | "submodule";
|
|
17
17
|
/** Complete Git-index record used by staged validation before any filtering. */
|
|
18
18
|
export interface StagedPath extends StagedFile {
|
|
19
|
+
/** Source path for a copy; unlike oldPath, it remains in the tree. */
|
|
20
|
+
copyFromPath?: string;
|
|
19
21
|
analysisDepth: StagedAnalysisDepth;
|
|
20
22
|
disposition: StagedDisposition;
|
|
21
23
|
gitMode?: string;
|
|
24
|
+
previousMode?: string;
|
|
25
|
+
oldHunkRanges?: HunkRange[];
|
|
22
26
|
previousContent?: string;
|
|
23
27
|
skipReason?: StagedSkipReason;
|
|
24
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-staged.d.ts","sourceRoot":"","sources":["../../src/traceability/git-staged.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git-staged.d.ts","sourceRoot":"","sources":["../../src/traceability/git-staged.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEvD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAC1E,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AACnE,MAAM,MAAM,gBAAgB,GACxB,QAAQ,GACR,sBAAsB,GACtB,SAAS,GACT,WAAW,CAAC;AAEhB,gFAAgF;AAChF,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,mBAAmB,CAAC;IACnC,WAAW,EAAE,iBAAiB,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAED,KAAK,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,KAAK,MAAM,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC;AAgChE;;GAEG;AAEH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,GACZ,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAwB5C;AAsFD;;;;GAIG;AAEH,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,UAAU,EAAE,CAmGrE;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,SAAS,UAAU,EAAE,GAC/B,UAAU,EAAE,CAmBd;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAEhC,QAAQ,EAAE,MAAM,EAChB,SAAS,UAAQ,GAChB,SAAS,EAAE,CAuBb;AAED;;GAEG;AAEH,wBAAgB,cAAc,CAAC,IAAI,GAAE,MAAoB,GAAG,UAAU,EAAE,CAwGvE;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
2
|
import { isCliTraceOrDebugEnabled } from "../env.js";
|
|
3
3
|
import { isEntityLanePath, isSymbolsManifestPath } from "../utils/kb-paths.js";
|
|
4
|
+
import { captureStagedSnapshot } from "./git-change-snapshot.js";
|
|
4
5
|
// Staged manifests (e.g., .kb/symbols.yaml) can exceed Node's default 1 MiB
|
|
5
6
|
// exec buffer; without a larger bound the staged file is silently skipped and
|
|
6
7
|
// freshness checks compare against stale HEAD state.
|
|
@@ -8,13 +9,6 @@ const GIT_EXEC_MAX_BUFFER = 64 * 1024 * 1024;
|
|
|
8
9
|
function defaultExec(cmd, opts) {
|
|
9
10
|
return execSync(cmd, { ...opts, maxBuffer: GIT_EXEC_MAX_BUFFER });
|
|
10
11
|
}
|
|
11
|
-
function defaultGitArgsExec(args) {
|
|
12
|
-
return execFileSync("git", args, {
|
|
13
|
-
encoding: "buffer",
|
|
14
|
-
maxBuffer: GIT_EXEC_MAX_BUFFER,
|
|
15
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
12
|
function runGitArgs(args, exec) {
|
|
19
13
|
try {
|
|
20
14
|
return exec(args);
|
|
@@ -138,10 +132,17 @@ function normalizeNewFileHunks(ranges, content) {
|
|
|
138
132
|
* than the working tree.
|
|
139
133
|
*/
|
|
140
134
|
// implements REQ-014
|
|
141
|
-
export function getStagedInventory(exec
|
|
135
|
+
export function getStagedInventory(exec) {
|
|
136
|
+
// The normal path reads only immutable tree/blob object IDs captured from the
|
|
137
|
+
// index. Keep the injectable reader path for existing callers and tests.
|
|
138
|
+
if (!exec) {
|
|
139
|
+
const snapshot = captureStagedSnapshot(process.cwd());
|
|
140
|
+
snapshot.assertUnchanged();
|
|
141
|
+
return snapshot.inventory;
|
|
142
|
+
}
|
|
142
143
|
let parsed;
|
|
143
144
|
try {
|
|
144
|
-
parsed = parseNameStatusNull(runGitArgs(["diff", "--cached", "--name-status", "-z", "--diff-filter=
|
|
145
|
+
parsed = parseNameStatusNull(runGitArgs(["diff", "--cached", "--name-status", "-z", "--diff-filter=ACMRTDC"], exec).toString("utf8"));
|
|
145
146
|
}
|
|
146
147
|
catch (error) {
|
|
147
148
|
throw new Error(`failed to list staged files: ${String(error)}`);
|
|
@@ -149,7 +150,8 @@ export function getStagedInventory(exec = defaultGitArgsExec) {
|
|
|
149
150
|
return parsed.map((entry) => {
|
|
150
151
|
const status = entry.status[0] || "M";
|
|
151
152
|
const oldPath = status === "R" ? entry.parts[0] : undefined;
|
|
152
|
-
const
|
|
153
|
+
const copyFromPath = status === "C" ? entry.parts[0] : undefined;
|
|
154
|
+
const path = status === "R" || status === "C"
|
|
153
155
|
? (entry.parts[1] ?? entry.parts[0] ?? "")
|
|
154
156
|
: (entry.parts[0] ?? "");
|
|
155
157
|
const lookupPath = status === "D" ? (oldPath ?? path) : path;
|
|
@@ -162,6 +164,7 @@ export function getStagedInventory(exec = defaultGitArgsExec) {
|
|
|
162
164
|
path,
|
|
163
165
|
status,
|
|
164
166
|
...(oldPath ? { oldPath } : {}),
|
|
167
|
+
...(copyFromPath ? { copyFromPath } : {}),
|
|
165
168
|
hunkRanges: [],
|
|
166
169
|
gitMode,
|
|
167
170
|
analysisDepth: "none",
|
|
@@ -179,6 +182,7 @@ export function getStagedInventory(exec = defaultGitArgsExec) {
|
|
|
179
182
|
path,
|
|
180
183
|
status,
|
|
181
184
|
...(oldPath ? { oldPath } : {}),
|
|
185
|
+
...(copyFromPath ? { copyFromPath } : {}),
|
|
182
186
|
hunkRanges,
|
|
183
187
|
diffText,
|
|
184
188
|
...(gitMode ? { gitMode } : {}),
|
|
@@ -202,6 +206,7 @@ export function getStagedInventory(exec = defaultGitArgsExec) {
|
|
|
202
206
|
path,
|
|
203
207
|
status,
|
|
204
208
|
...(oldPath ? { oldPath } : {}),
|
|
209
|
+
...(copyFromPath ? { copyFromPath } : {}),
|
|
205
210
|
hunkRanges,
|
|
206
211
|
diffText,
|
|
207
212
|
...(content !== undefined ? { content } : {}),
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { SourceChangeAnalysis } from "../plugins/source-change-analysis.js";
|
|
2
|
+
import type { GitChangeSnapshot } from "./git-change-snapshot.js";
|
|
3
|
+
import type { StagedPath } from "./git-staged.js";
|
|
4
|
+
import { type EntityRow } from "./impact-knowledge.js";
|
|
5
|
+
import { type AnalysisReview, type Fingerprint, type ImpactDecision, type ImpactFileRecord, type ImpactPolicy, type ImpactReviewDiagnostic, type ImpactReviewRecord } from "./impact-review.js";
|
|
6
|
+
export type ImpactPreparationOptions = Readonly<{
|
|
7
|
+
/** Resolved by the trusted host from its approved provider closure. */
|
|
8
|
+
providerSetFingerprint: Fingerprint;
|
|
9
|
+
/** Hash of the trusted evaluator/normalizers in the host package. */
|
|
10
|
+
evaluatorFingerprint: Fingerprint;
|
|
11
|
+
/** Both sides must be analyzed from snapshot bytes before preparation. */
|
|
12
|
+
analyses: ReadonlyMap<string, SourceChangeAnalysis>;
|
|
13
|
+
}>;
|
|
14
|
+
export type PreparedImpactReview = Readonly<{
|
|
15
|
+
policy: ImpactPolicy;
|
|
16
|
+
policyFingerprint: Fingerprint;
|
|
17
|
+
evaluatorFingerprint: Fingerprint;
|
|
18
|
+
providerSetFingerprint: Fingerprint;
|
|
19
|
+
knowledgeFingerprint: Fingerprint;
|
|
20
|
+
scopeFingerprint: Fingerprint;
|
|
21
|
+
files: readonly Omit<ImpactFileRecord, "decision">[];
|
|
22
|
+
scopedRequirementIdsByPath: ReadonlyMap<string, readonly string[]>;
|
|
23
|
+
baseEntities: ReadonlyMap<string, EntityRow>;
|
|
24
|
+
headEntities: ReadonlyMap<string, EntityRow>;
|
|
25
|
+
/** Exact impact record digest input, excluding only the record path. */
|
|
26
|
+
scopePayload: unknown;
|
|
27
|
+
}>;
|
|
28
|
+
export type ImpactEvaluation = Readonly<{
|
|
29
|
+
passed: boolean;
|
|
30
|
+
scopeFingerprint?: Fingerprint;
|
|
31
|
+
diagnostics: readonly ImpactReviewDiagnostic[];
|
|
32
|
+
/** Local review is self-claimed and never an authorization attestation. */
|
|
33
|
+
reviewerAuthority: "self-claimed-local" | "none";
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Identify the trusted evaluator by the contract it implements, not by where
|
|
37
|
+
* it is installed. The identity is the evaluator contract version plus the
|
|
38
|
+
* canonical JSON of every schema the evaluator and KB normalization consume.
|
|
39
|
+
* Schemas are imported (and therefore inlined by bundlers), so the CLI, the
|
|
40
|
+
* bundled runtime and CI compute the same value for the same release on any
|
|
41
|
+
* machine or Node version. Bump IMPACT_EVALUATOR_VERSION whenever decision
|
|
42
|
+
* semantics change so reviews bound to the old evaluator become stale.
|
|
43
|
+
*/
|
|
44
|
+
export declare function fingerprintImpactEvaluator(): Fingerprint;
|
|
45
|
+
export declare function prepareImpactReview(snapshot: GitChangeSnapshot, options: ImpactPreparationOptions): PreparedImpactReview;
|
|
46
|
+
export declare function createImpactReviewRecord(prepared: PreparedImpactReview, decisions: ReadonlyMap<string, Readonly<{
|
|
47
|
+
decision: ImpactDecision;
|
|
48
|
+
analysisReviews?: readonly AnalysisReview[];
|
|
49
|
+
}>>, reviewerId: string, reviewedAt?: string): ImpactReviewRecord;
|
|
50
|
+
export declare function evaluateImpactReview(snapshot: GitChangeSnapshot, options: ImpactPreparationOptions): ImpactEvaluation;
|
|
51
|
+
/** Verify that the transport path is unique and that no second path is excluded. */
|
|
52
|
+
export declare function impactReviewInventory(snapshot: GitChangeSnapshot): readonly StagedPath[];
|
|
53
|
+
export { hasValidBaseImpactPolicy, impactPolicyFingerprint, loadBaseImpactPolicy, } from "./impact-policy.js";
|
|
54
|
+
//# sourceMappingURL=impact-evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impact-evaluator.d.ts","sourceRoot":"","sources":["../../src/traceability/impact-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAGjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EACL,KAAK,SAAS,EAKf,MAAM,uBAAuB,CAAC;AAW/B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,WAAW,EAIhB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EAIxB,MAAM,oBAAoB,CAAC;AAY5B,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,uEAAuE;IACvE,sBAAsB,EAAE,WAAW,CAAC;IACpC,qEAAqE;IACrE,oBAAoB,EAAE,WAAW,CAAC;IAClC,0EAA0E;IAC1E,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CACrD,CAAC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,MAAM,EAAE,YAAY,CAAC;IACrB,iBAAiB,EAAE,WAAW,CAAC;IAC/B,oBAAoB,EAAE,WAAW,CAAC;IAClC,sBAAsB,EAAE,WAAW,CAAC;IACpC,oBAAoB,EAAE,WAAW,CAAC;IAClC,gBAAgB,EAAE,WAAW,CAAC;IAC9B,KAAK,EAAE,SAAS,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,EAAE,CAAC;IACrD,0BAA0B,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IACnE,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC7C,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC7C,wEAAwE;IACxE,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC/B,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC/C,2EAA2E;IAC3E,iBAAiB,EAAE,oBAAoB,GAAG,MAAM,CAAC;CAClD,CAAC,CAAC;AAEH;;;;;;;;GAQG;AAEH,wBAAgB,0BAA0B,IAAI,WAAW,CAUxD;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,wBAAwB,GAChC,oBAAoB,CAoJtB;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,EAAE,WAAW,CACpB,MAAM,EACN,QAAQ,CAAC;IACP,QAAQ,EAAE,cAAc,CAAC;IACzB,eAAe,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CAC7C,CAAC,CACH,EACD,UAAU,EAAE,MAAM,EAClB,UAAU,SAA2B,GACpC,kBAAkB,CAyCpB;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,wBAAwB,GAChC,gBAAgB,CAsFlB;AAED,oFAAoF;AACpF,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,iBAAiB,GAC1B,SAAS,UAAU,EAAE,CAmBvB;AAED,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC"}
|