kibi-cli 2.0.0 → 2.2.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-protocol.d.ts.map +1 -1
- package/dist/cli-protocol.js +3 -2
- package/dist/cli-register-proof.d.ts.map +1 -1
- package/dist/cli-register-proof.js +25 -1
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +6 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -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-generated.d.ts +7 -0
- package/dist/commands/check-generated.d.ts.map +1 -0
- package/dist/commands/check-generated.js +192 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +24 -15
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +227 -25
- package/dist/commands/engine.d.ts.map +1 -1
- package/dist/commands/engine.js +3 -1
- 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 +1 -1
- 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 +136 -30
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +110 -15
- package/dist/commands/proof-explain.d.ts +10 -0
- package/dist/commands/proof-explain.d.ts.map +1 -0
- package/dist/commands/proof-explain.js +45 -0
- package/dist/commands/proof-impact.d.ts +7 -0
- package/dist/commands/proof-impact.d.ts.map +1 -0
- package/dist/commands/proof-impact.js +39 -0
- package/dist/commands/proof-migrate-legacy.js +1 -1
- package/dist/commands/proof-prune.js +1 -1
- package/dist/commands/prove.d.ts.map +1 -1
- package/dist/commands/prove.js +14 -22
- package/dist/commands/report.d.ts.map +1 -1
- package/dist/commands/report.js +17 -2
- 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 +1 -0
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +18 -16
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +14 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +11 -3
- package/dist/engine.d.ts +29 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +259 -89
- package/dist/env/bootstrap.d.ts +84 -0
- package/dist/env/bootstrap.d.ts.map +1 -0
- package/dist/env/bootstrap.js +310 -0
- package/dist/extractors/manifest.d.ts.map +1 -1
- package/dist/extractors/manifest.js +67 -29
- package/dist/extractors/markdown.d.ts +4 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +33 -3
- package/dist/extractors/relationships.d.ts.map +1 -1
- package/dist/extractors/relationships.js +1 -0
- package/dist/extractors/symbols-coordinator.d.ts +8 -0
- package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.js +40 -0
- package/dist/extractors/symbols-ts.d.ts +8 -19
- package/dist/extractors/symbols-ts.d.ts.map +1 -1
- package/dist/extractors/symbols-ts.js +33 -503
- package/dist/intent-search.d.ts.map +1 -1
- package/dist/intent-search.js +68 -30
- 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 +179 -9
- 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-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/suggest-predicates.d.ts +1 -1
- package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
- package/dist/operations/modeling/suggest-predicates.js +30 -3
- 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 +65 -26
- package/dist/operations/mutation/strict-fact.d.ts.map +1 -1
- package/dist/operations/mutation/strict-fact.js +5 -0
- package/dist/operations/mutation/symbol-granularity.d.ts.map +1 -1
- package/dist/operations/mutation/symbol-granularity.js +9 -87
- 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 +72 -4
- 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 +61 -17
- package/dist/operations/planning/compile-intent.d.ts +49 -0
- package/dist/operations/planning/compile-intent.d.ts.map +1 -1
- package/dist/operations/planning/compile-intent.js +66 -4
- package/dist/operations/proof/baseline-diff.d.ts +41 -0
- package/dist/operations/proof/baseline-diff.d.ts.map +1 -0
- package/dist/operations/proof/baseline-diff.js +153 -0
- 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/explain.d.ts +75 -0
- package/dist/operations/proof/explain.d.ts.map +1 -0
- package/dist/operations/proof/explain.js +294 -0
- package/dist/operations/proof/impact.d.ts +45 -0
- package/dist/operations/proof/impact.d.ts.map +1 -0
- package/dist/operations/proof/impact.js +118 -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 +251 -77
- package/dist/operations/proof/migrate-legacy-receipts.d.ts.map +1 -1
- package/dist/operations/proof/migrate-legacy-receipts.js +28 -22
- package/dist/operations/proof/prune-receipts.d.ts.map +1 -1
- package/dist/operations/proof/prune-receipts.js +8 -6
- package/dist/operations/proof/receipt-document.js +2 -2
- package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analysis-receipt.js +3 -9
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +18 -67
- package/dist/operations/semantic-advisor/plugin-orchestration.d.ts +63 -0
- package/dist/operations/semantic-advisor/plugin-orchestration.d.ts.map +1 -0
- package/dist/operations/semantic-advisor/plugin-orchestration.js +489 -0
- package/dist/operations/semantic-advisor/predicate-rules-core.d.ts +15 -2
- package/dist/operations/semantic-advisor/predicate-rules-core.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/predicate-rules-core.js +7 -140
- package/dist/operations/semantic-advisor/predicate-rules-launcher.d.ts +11 -12
- package/dist/operations/semantic-advisor/predicate-rules-launcher.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/predicate-rules-launcher.js +6 -94
- package/dist/operations/semantic-advisor/predicate-rules-policy.d.ts +16 -0
- package/dist/operations/semantic-advisor/predicate-rules-policy.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/predicate-rules-policy.js +7 -150
- package/dist/operations/semantic-advisor/predicate-rules-product-tail.d.ts +9 -0
- package/dist/operations/semantic-advisor/predicate-rules-product-tail.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/predicate-rules-product-tail.js +7 -102
- package/dist/operations/semantic-advisor/predicate-rules-product.d.ts +13 -0
- package/dist/operations/semantic-advisor/predicate-rules-product.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/predicate-rules-product.js +7 -133
- package/dist/operations/semantic-advisor/types.d.ts +1 -0
- package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
- package/dist/plugins/compose-ontology-packs.d.ts +51 -0
- package/dist/plugins/compose-ontology-packs.d.ts.map +1 -0
- package/dist/plugins/compose-ontology-packs.js +257 -0
- package/dist/plugins/compose-semantic-classifier.d.ts +47 -0
- package/dist/plugins/compose-semantic-classifier.d.ts.map +1 -0
- package/dist/plugins/compose-semantic-classifier.js +216 -0
- 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 +17 -0
- package/dist/plugins/external-allowlist.d.ts.map +1 -0
- package/dist/plugins/external-allowlist.js +29 -0
- package/dist/plugins/index.d.ts +11 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +37 -0
- package/dist/plugins/load-plugin.d.ts +19 -0
- package/dist/plugins/load-plugin.d.ts.map +1 -0
- package/dist/plugins/load-plugin.js +59 -0
- package/dist/plugins/project-config.d.ts +28 -0
- package/dist/plugins/project-config.d.ts.map +1 -0
- package/dist/plugins/project-config.js +90 -0
- package/dist/plugins/registry.d.ts +94 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +359 -0
- package/dist/plugins/resolve-package.d.ts +47 -0
- package/dist/plugins/resolve-package.d.ts.map +1 -0
- package/dist/plugins/resolve-package.js +262 -0
- package/dist/plugins/source-analysis-service.d.ts +44 -0
- package/dist/plugins/source-analysis-service.d.ts.map +1 -0
- package/dist/plugins/source-analysis-service.js +232 -0
- package/dist/prolog/codec.d.ts.map +1 -1
- package/dist/prolog/codec.js +2 -0
- package/dist/prolog/janitor.d.ts.map +1 -1
- package/dist/prolog/janitor.js +1 -1
- package/dist/prolog/store-lock.d.ts +1 -1
- package/dist/prolog/store-lock.d.ts.map +1 -1
- package/dist/prolog.d.ts +36 -0
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +78 -9
- package/dist/proof/inspect.js +1 -1
- package/dist/proof/producers/playwright-case-id.js +2 -2
- package/dist/proof/producers/playwright-reporter.js +4 -4
- package/dist/public/diagnostic-usage.d.ts.map +1 -1
- package/dist/public/diagnostic-usage.js +7 -25
- package/dist/public/extractors/symbols-coordinator.d.ts +1 -1
- package/dist/public/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/public/extractors/symbols-coordinator.js +1 -1
- package/dist/public/impact/analyzer.d.ts +1 -1
- package/dist/public/impact/analyzer.d.ts.map +1 -1
- package/dist/public/impact/analyzer.js +6 -4
- 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/operations/catalog.d.ts +39 -7
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +11 -3
- package/dist/public/operations/check-helpers.d.ts +7 -1
- package/dist/public/operations/check-helpers.d.ts.map +1 -1
- package/dist/public/operations/check-helpers.js +22 -2
- package/dist/public/operations/contracts.d.ts.map +1 -1
- package/dist/public/operations/contracts.js +51 -12
- package/dist/public/operations/discovery-entities.d.ts +53 -1
- package/dist/public/operations/discovery-entities.d.ts.map +1 -1
- package/dist/public/operations/discovery-entities.js +219 -12
- 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 +93 -59
- 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/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 +1 -1
- package/dist/public/operations/prolog-json.d.ts.map +1 -1
- package/dist/public/operations/prolog-json.js +16 -10
- 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 +17 -2
- 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 +9 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/discovery.d.ts +10 -1
- package/dist/public/operations/specs/discovery.d.ts.map +1 -1
- package/dist/public/operations/specs/discovery.js +10 -1
- 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/proof.js +1 -1
- package/dist/public/operations/specs/reporting.d.ts +9 -0
- package/dist/public/operations/specs/reporting.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.js +48 -17
- package/dist/public/operations/specs/semantic.d.ts +1 -1
- package/dist/public/operations/specs/semantic.d.ts.map +1 -1
- package/dist/public/operations/specs/semantic.js +54 -4
- 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 +11 -4
- package/dist/public/operations/types.d.ts +5 -0
- package/dist/public/operations/types.d.ts.map +1 -1
- package/dist/public/proof-protocol.js +4 -4
- 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 +10 -3
- package/dist/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
- package/dist/public/skills/kibi-usage/resources/proof.md +45 -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/symbol-granularity.d.ts +1 -1
- package/dist/public/symbol-granularity.d.ts.map +1 -1
- package/dist/public/symbol-granularity.generated.d.ts.map +1 -1
- package/dist/public/symbol-granularity.generated.js +38 -5
- 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/report/html-report.css +1239 -281
- package/dist/runtime/cli-runtime.d.ts.map +1 -1
- package/dist/runtime/cli-runtime.js +18 -0
- package/dist/schemas/entity.schema.json +32 -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/symbol-extract.d.ts +24 -7
- package/dist/traceability/symbol-extract.d.ts.map +1 -1
- package/dist/traceability/symbol-extract.js +64 -208
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +8 -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/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 +42 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +50 -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 -11
- 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/extractors/symbols-coordinator.ts +1 -0
- package/src/public/impact/analyzer.ts +15 -12
- package/src/public/impact/full-kb-quality.ts +4 -16
- package/src/public/operations/check-executor.ts +13 -2
- package/src/public/operations/check-helpers.ts +29 -3
- package/src/public/operations/contracts.ts +59 -12
- package/src/public/operations/discovery-entities.ts +327 -12
- package/src/public/operations/discovery-executors.ts +110 -61
- package/src/public/operations/migration-plan.ts +57 -0
- package/src/public/operations/predicate-schema-conformance.ts +362 -0
- package/src/public/operations/prolog-json.ts +22 -8
- package/src/public/operations/result-envelope.ts +114 -2
- package/src/public/operations/runtime-types.ts +22 -3
- package/src/public/operations/specs/check-rules.generated.ts +9 -1
- package/src/public/operations/specs/discovery.ts +11 -1
- package/src/public/operations/specs/mutation-schemas.ts +23 -3
- package/src/public/operations/specs/proof.ts +1 -1
- package/src/public/operations/specs/reporting.ts +71 -24
- package/src/public/operations/specs/semantic.ts +79 -17
- package/src/public/operations/specs/upsert.ts +1 -1
- package/src/public/operations/symbol-repair-plan.ts +16 -7
- package/src/public/operations/types.ts +5 -0
- package/src/public/proof-fingerprint.ts +1 -1
- package/src/public/proof-protocol-types.d.ts +1 -1
- package/src/public/proof-protocol.ts +4 -4
- package/src/public/schemas/entity.ts +22 -0
- package/src/public/schemas/relationship.ts +1 -0
- package/src/public/skills/kibi-usage/SKILL.md +10 -3
- package/src/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
- package/src/public/skills/kibi-usage/resources/proof.md +45 -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/symbol-granularity.generated.ts +45 -12
- package/src/public/symbol-granularity.ts +3 -3
- package/src/public/telemetry-acceptance.ts +37 -6
- package/src/schemas/entity.schema.json +32 -0
- package/src/schemas/relationship.schema.json +1 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
3
|
+
Copyright (C) 2026 Piotr Franczyk
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
*/
|
|
10
|
+
import { execFileSync } from "node:child_process";
|
|
11
|
+
import { executeCoverage } from "../../public/operations/specs/reporting.js";
|
|
12
|
+
import { diffFingerprints, fingerprintRequirements, renderRequirementDiffs, } from "./baseline-diff.js";
|
|
13
|
+
// implements REQ-kibi-verification-evidence-contract
|
|
14
|
+
export const COMMITTED_BASELINE_PATH = "proof/baseline.json";
|
|
15
|
+
function asNumber(value) {
|
|
16
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
17
|
+
}
|
|
18
|
+
function gitErrorText(error) {
|
|
19
|
+
if (error && typeof error === "object" && "stderr" in error) {
|
|
20
|
+
const stderr = error.stderr;
|
|
21
|
+
if (typeof stderr === "string" && stderr.trim() !== "")
|
|
22
|
+
return stderr;
|
|
23
|
+
if (Buffer.isBuffer(stderr) && stderr.length > 0) {
|
|
24
|
+
return stderr.toString("utf8");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return error instanceof Error ? error.message : String(error);
|
|
28
|
+
}
|
|
29
|
+
function committedBaselineReadError(relativePath, error) {
|
|
30
|
+
const text = gitErrorText(error);
|
|
31
|
+
if (/not a git repository/i.test(text) ||
|
|
32
|
+
/ambiguous argument 'HEAD'/i.test(text) ||
|
|
33
|
+
/unknown revision/i.test(text) ||
|
|
34
|
+
/needed a single revision/i.test(text) ||
|
|
35
|
+
/bad revision 'HEAD'/i.test(text)) {
|
|
36
|
+
return new Error(`proof impact: repository is not in a suitable Git state to read HEAD:${relativePath}`);
|
|
37
|
+
}
|
|
38
|
+
if (/does not exist in 'HEAD'/i.test(text) ||
|
|
39
|
+
/exists on disk, but not in 'HEAD'/i.test(text) ||
|
|
40
|
+
/path '.*' does not exist/i.test(text)) {
|
|
41
|
+
return new Error(`proof impact: HEAD:${relativePath} is missing or unreadable`);
|
|
42
|
+
}
|
|
43
|
+
return new Error(`proof impact: could not read HEAD:${relativePath}: ${text.trim()}`);
|
|
44
|
+
}
|
|
45
|
+
// implements REQ-kibi-verification-evidence-contract
|
|
46
|
+
export function readCommittedHeadFile(workspaceRoot, relativePath) {
|
|
47
|
+
try {
|
|
48
|
+
return execFileSync("git", ["-C", workspaceRoot, "show", `HEAD:${relativePath}`], {
|
|
49
|
+
encoding: "utf8",
|
|
50
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
51
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
throw committedBaselineReadError(relativePath, error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// implements REQ-kibi-verification-evidence-contract
|
|
59
|
+
export async function loadCommittedBaseline(workspaceRoot, readCommittedFile = readCommittedHeadFile) {
|
|
60
|
+
const raw = await readCommittedFile(workspaceRoot, COMMITTED_BASELINE_PATH);
|
|
61
|
+
try {
|
|
62
|
+
return JSON.parse(raw);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
throw new Error(`proof impact: HEAD:${COMMITTED_BASELINE_PATH} is not valid JSON`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Diagnostic only: successful evaluation always exits 0. Ratchet lives in check-proof-baseline.mjs. */
|
|
69
|
+
export function proofImpactExitCode(_result) {
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
// implements REQ-kibi-verification-evidence-contract
|
|
73
|
+
export function buildProofImpact(baseline, coverage) {
|
|
74
|
+
const rows = Array.isArray(coverage.rows)
|
|
75
|
+
? coverage.rows
|
|
76
|
+
: [];
|
|
77
|
+
const summary = coverage.summary ?? {};
|
|
78
|
+
const proofNotApplicable = asNumber(summary.proofNotApplicable);
|
|
79
|
+
const total = asNumber(summary.total);
|
|
80
|
+
const proofProven = asNumber(summary.proofProven);
|
|
81
|
+
const currentUnproven = asNumber(summary.proofMissing) + asNumber(summary.proofUnresolved);
|
|
82
|
+
const current = fingerprintRequirements(rows);
|
|
83
|
+
const changes = diffFingerprints(baseline.requirements, current);
|
|
84
|
+
return {
|
|
85
|
+
rows,
|
|
86
|
+
result: {
|
|
87
|
+
comparisonTarget: COMMITTED_BASELINE_PATH,
|
|
88
|
+
baselineVersion: baseline.version ?? "unknown",
|
|
89
|
+
currentRequirements: total - proofNotApplicable,
|
|
90
|
+
proofProven,
|
|
91
|
+
currentUnproven,
|
|
92
|
+
changes,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// implements REQ-kibi-verification-evidence-contract
|
|
97
|
+
export function renderProofImpact(result, rows) {
|
|
98
|
+
const header = [
|
|
99
|
+
`Proof impact compared to committed ${result.comparisonTarget}`,
|
|
100
|
+
`baseline version: ${result.baselineVersion}`,
|
|
101
|
+
`current requirements: ${result.currentRequirements}`,
|
|
102
|
+
`proofProven: ${result.proofProven}`,
|
|
103
|
+
`currentUnproven: ${result.currentUnproven}`,
|
|
104
|
+
`changed requirements: ${result.changes.length}`,
|
|
105
|
+
"",
|
|
106
|
+
];
|
|
107
|
+
const diff = renderRequirementDiffs(result.changes, rows);
|
|
108
|
+
return `${header.join("\n")}${diff || "No requirement fingerprint changes versus the committed baseline.\n"}`;
|
|
109
|
+
}
|
|
110
|
+
// implements REQ-kibi-verification-evidence-contract
|
|
111
|
+
export async function executeProofImpact(context, options = {}) {
|
|
112
|
+
const baseline = await loadCommittedBaseline(context.workspaceRoot, options.readCommittedFile ?? readCommittedHeadFile);
|
|
113
|
+
const coverage = options.loadCoverage
|
|
114
|
+
? await options.loadCoverage(context)
|
|
115
|
+
: await executeCoverage({ by: "req", includePassing: true, limit: 100_000, offset: 0 }, context);
|
|
116
|
+
const { result, rows } = buildProofImpact(baseline, coverage.structuredContent);
|
|
117
|
+
return { result, rows, text: renderProofImpact(result, rows) };
|
|
118
|
+
}
|
|
@@ -24,11 +24,13 @@ export type IngestProofResult = Readonly<{
|
|
|
24
24
|
unchanged: number;
|
|
25
25
|
results: readonly IngestProofTestResult[];
|
|
26
26
|
}>;
|
|
27
|
-
|
|
27
|
+
type IngestProofOutput = {
|
|
28
28
|
content: Array<{
|
|
29
29
|
type: "text";
|
|
30
30
|
text: string;
|
|
31
31
|
}>;
|
|
32
32
|
structuredContent: IngestProofResult;
|
|
33
|
-
}
|
|
33
|
+
};
|
|
34
|
+
export declare function executeIngestProof(args: IngestProofArgs, context: OperationContext): Promise<IngestProofOutput>;
|
|
35
|
+
export {};
|
|
34
36
|
//# sourceMappingURL=ingest-proof.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingest-proof.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/ingest-proof.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ingest-proof.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/ingest-proof.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,QAAQ,EAEd,MAAM,yBAAyB,CAAC;AAOjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAkBjF,OAAO,EAEL,KAAK,YAAY,EAGlB,MAAM,+BAA+B,CAAC;AAqBvC,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;CAC3B,CAAC,CAAC;AAGH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC3C,CAAC,CAAC;AAEH,KAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,iBAAiB,CAAC;CACtC,CAAC;AAokBF,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAuC5B"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { resolveBoundSymbolScope } from "../../extractors/manifest.js";
|
|
3
|
+
import { loadCoveredBySymbolsByTest, receiptCodeScopeSymbolIds, } from "./code-scope.js";
|
|
1
4
|
import { evaluateContractAgainstRun, } from "../../proof/evaluate.js";
|
|
2
5
|
import { loadProofIntegrations, resolveIntegration, toExecution, } from "../../proof/integrations.js";
|
|
3
6
|
import { loadEntities } from "../../public/operations/discovery-entities.js";
|
|
@@ -6,11 +9,33 @@ import { environmentHash as canonicalEnvironmentHash, effectiveProofFingerprint,
|
|
|
6
9
|
import { PROOF_CONTRACT_VERSION, PROOF_RECEIPT_VERSION, proofBindingsErrors, proofRunArtifactErrors, } from "../../public/proof-protocol.js";
|
|
7
10
|
import { MAX_PROOF_RECEIPTS, proofReceiptCurrentBindingErrors, proofReceiptHistoryErrors, } from "../../public/proof-receipt.js";
|
|
8
11
|
import { projectEntityProperties } from "../mutation/entity-projection.js";
|
|
9
|
-
import { join } from "node:path";
|
|
10
|
-
import { resolveBoundSymbolScope } from "../../extractors/manifest.js";
|
|
11
12
|
import { resolveContainedSourcePath } from "../mutation/source-authoring.js";
|
|
13
|
+
import { buildUpsertBatchCommitGoal, parseUpsertChangeKinds, } from "../mutation/contradictions.js";
|
|
12
14
|
import { executeUpsert } from "../mutation/upsert.js";
|
|
15
|
+
import { acquireWorkspaceMutationLock, releaseWorkspaceMutationLock, } from "../mutation/workspace-mutation-lock.js";
|
|
16
|
+
import { MutationRollbackFailureError } from "../mutation/saga.js";
|
|
13
17
|
import { patchReceiptsIntoDocument, removeFrontmatterBlock, } from "./receipt-document.js";
|
|
18
|
+
async function rollbackUncommittedReceipts(pending, originalError, lifecycle) {
|
|
19
|
+
const failures = [];
|
|
20
|
+
for (const entry of pending) {
|
|
21
|
+
if (entry.deferred.state === "committed")
|
|
22
|
+
continue;
|
|
23
|
+
try {
|
|
24
|
+
const rollbackFailures = await entry.deferred.rollback();
|
|
25
|
+
for (const failure of rollbackFailures) {
|
|
26
|
+
failures.push({ testId: entry.testId, ...failure });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
failures.push({ testId: entry.testId, step: "rollback", error });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (failures.length > 0) {
|
|
34
|
+
lifecycle?.onRollbackFailure?.();
|
|
35
|
+
throw new AggregateError([originalError, ...failures.map((failure) => failure.error)], `Proof ingest failed and could not restore every uncommitted receipt source; the source mutation lock remains held for recovery (${failures.map(({ testId, step }) => `${testId}:${step}`).join(", ")})`);
|
|
36
|
+
}
|
|
37
|
+
throw originalError;
|
|
38
|
+
}
|
|
14
39
|
function text(value) {
|
|
15
40
|
return typeof value === "string" ? value.trim() : "";
|
|
16
41
|
}
|
|
@@ -74,13 +99,53 @@ function parseBindings(test) {
|
|
|
74
99
|
};
|
|
75
100
|
});
|
|
76
101
|
}
|
|
102
|
+
function enforceNativeCaseBindings(testId, contract, bindings, artifact) {
|
|
103
|
+
const requiredKeys = new Set(contract.required_proofs.map((obligation) => `${obligation.target}\0${obligation.symbol_id}`));
|
|
104
|
+
const nativeResults = artifact.proof_results.filter((result) => result.binding === "native_case" &&
|
|
105
|
+
requiredKeys.has(`${result.target}\0${result.symbol_id}`));
|
|
106
|
+
const seenNativeIds = new Set();
|
|
107
|
+
for (const result of nativeResults) {
|
|
108
|
+
const nativeId = typeof result.native_id === "string" ? result.native_id : "";
|
|
109
|
+
const resultLabel = `${result.symbol_id}/${result.target}`;
|
|
110
|
+
if (!nativeId) {
|
|
111
|
+
throw new Error(`Proof ingest failed: test ${testId} native_case result ${resultLabel} has no native_id`);
|
|
112
|
+
}
|
|
113
|
+
if (seenNativeIds.has(nativeId)) {
|
|
114
|
+
throw new Error(`Proof ingest failed: test ${testId} duplicate native result for native_id '${nativeId}'`);
|
|
115
|
+
}
|
|
116
|
+
seenNativeIds.add(nativeId);
|
|
117
|
+
const matchingBindings = bindings.filter((binding) => binding.symbol_id === result.symbol_id &&
|
|
118
|
+
binding.target === result.target);
|
|
119
|
+
if (matchingBindings.length === 0) {
|
|
120
|
+
throw new Error(`Proof ingest failed: test ${testId} native_case result ${resultLabel} has no matching proof_binding`);
|
|
121
|
+
}
|
|
122
|
+
if (matchingBindings.length !== 1) {
|
|
123
|
+
throw new Error(`Proof ingest failed: test ${testId} native_case result ${resultLabel} has an ambiguous proof_binding`);
|
|
124
|
+
}
|
|
125
|
+
const binding = matchingBindings[0];
|
|
126
|
+
if (binding === undefined) {
|
|
127
|
+
throw new Error(`Proof ingest failed: test ${testId} native_case result ${resultLabel} has an ambiguous proof_binding`);
|
|
128
|
+
}
|
|
129
|
+
const boundNativeIds = [
|
|
130
|
+
binding.native_id,
|
|
131
|
+
...(binding.aliases ?? []),
|
|
132
|
+
].filter((value) => typeof value === "string" && value !== "");
|
|
133
|
+
if (!boundNativeIds.includes(nativeId)) {
|
|
134
|
+
throw new Error(`Proof ingest failed: test ${testId} native_case result ${resultLabel} native_id '${nativeId}' does not match its proof_binding native_id or aliases`);
|
|
135
|
+
}
|
|
136
|
+
const ambiguousOwners = bindings.filter((candidate) => [candidate.native_id, ...(candidate.aliases ?? [])].includes(nativeId));
|
|
137
|
+
if (ambiguousOwners.length !== 1) {
|
|
138
|
+
throw new Error(`Proof ingest failed: test ${testId} native_id '${nativeId}' has an ambiguous proof_binding`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
77
142
|
function existingReceipts(test) {
|
|
78
143
|
return Array.isArray(test.proof_receipts)
|
|
79
144
|
? test.proof_receipts.filter(record).map((value) => ({ ...value }))
|
|
80
145
|
: [];
|
|
81
146
|
}
|
|
82
|
-
// implements REQ-kibi-
|
|
83
|
-
|
|
147
|
+
// implements REQ-kibi-verification-evidence-contract
|
|
148
|
+
async function executeIngestProofUnlocked(args, context, lifecycle) {
|
|
84
149
|
if (!context.prolog)
|
|
85
150
|
throw new Error("Proof ingest requires a Prolog runtime");
|
|
86
151
|
const snapshot = requiredString(args.snapshot, "snapshot");
|
|
@@ -122,18 +187,37 @@ export async function executeIngestProof(args, context) {
|
|
|
122
187
|
}
|
|
123
188
|
}
|
|
124
189
|
else {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
190
|
+
// Select candidates from the paged contract projection (no receipt
|
|
191
|
+
// histories), then load each matching test in full: the append-only
|
|
192
|
+
// receipt update needs that test's existing history, but never every
|
|
193
|
+
// test's history in a single Prolog answer.
|
|
194
|
+
const candidates = await loadEntities(context.prolog, {
|
|
195
|
+
type: "test",
|
|
196
|
+
projection: "proof_contract",
|
|
197
|
+
});
|
|
198
|
+
for (const candidate of candidates) {
|
|
199
|
+
const contract = record(candidate.proof_contract);
|
|
200
|
+
if (!contract ||
|
|
201
|
+
contract.version !== PROOF_CONTRACT_VERSION ||
|
|
202
|
+
text(contract.integration) !== integrationId) {
|
|
203
|
+
continue;
|
|
132
204
|
}
|
|
205
|
+
const testId = String(candidate.id);
|
|
206
|
+
const found = await loadEntities(context.prolog, {
|
|
207
|
+
id: testId,
|
|
208
|
+
type: "test",
|
|
209
|
+
});
|
|
210
|
+
const test = found[0];
|
|
211
|
+
if (!test)
|
|
212
|
+
throw new Error(`Proof ingest failed: test ${testId} was not found`);
|
|
213
|
+
tests.push(test);
|
|
133
214
|
}
|
|
134
215
|
if (tests.length === 0)
|
|
135
216
|
throw new Error(`Proof ingest failed: no tests declare proof_contract.integration '${integrationId}'`);
|
|
136
217
|
}
|
|
218
|
+
// Loaded outside the per-test binding try/catch: an engine failure must fail
|
|
219
|
+
// the ingest, not silently write receipts without a binding hash.
|
|
220
|
+
const coveredBy = await loadCoveredBySymbolsByTest(context.prolog);
|
|
137
221
|
const prepared = [];
|
|
138
222
|
for (const test of tests) {
|
|
139
223
|
const testId = String(test.id);
|
|
@@ -147,6 +231,7 @@ export async function executeIngestProof(args, context) {
|
|
|
147
231
|
if (jsonDigest(artifact.command_argv) !== jsonDigest([...integration.command]))
|
|
148
232
|
throw new Error(`Proof ingest failed: artifact command_argv does not match the configured command for integration '${effectiveIntegrationId}'`);
|
|
149
233
|
const bindings = parseBindings(test);
|
|
234
|
+
enforceNativeCaseBindings(testId, contract, bindings, artifact);
|
|
150
235
|
const { fingerprint, components } = effectiveProofFingerprint({
|
|
151
236
|
contract,
|
|
152
237
|
integration: toExecution(integration),
|
|
@@ -166,7 +251,7 @@ export async function executeIngestProof(args, context) {
|
|
|
166
251
|
const absolute = resolveContainedSourcePath(context.workspaceRoot, source);
|
|
167
252
|
const authored = await context.fs.readFile(absolute);
|
|
168
253
|
const stripped = removeFrontmatterBlock(authored, "proof_receipts");
|
|
169
|
-
const codeScope = resolveBoundSymbolScope(join(context.workspaceRoot, ".kb", "symbols.yaml"), bindings.
|
|
254
|
+
const codeScope = resolveBoundSymbolScope(join(context.workspaceRoot, ".kb", "symbols.yaml"), receiptCodeScopeSymbolIds(contract, bindings, coveredBy.get(testId) ?? []));
|
|
170
255
|
bindingHash = receiptBindingHash(contract, stripped ?? authored, codeScope);
|
|
171
256
|
}
|
|
172
257
|
catch {
|
|
@@ -212,82 +297,138 @@ export async function executeIngestProof(args, context) {
|
|
|
212
297
|
});
|
|
213
298
|
}
|
|
214
299
|
const results = [];
|
|
300
|
+
const pendingCommits = [];
|
|
215
301
|
let passed = 0;
|
|
216
302
|
let failed = 0;
|
|
217
303
|
let unchanged = 0;
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
304
|
+
try {
|
|
305
|
+
for (const entry of prepared) {
|
|
306
|
+
const { testId, test, contract, evaluation, receipt, existing } = entry;
|
|
307
|
+
// Idempotent re-ingestion: the same artifact against the same effective
|
|
308
|
+
// contract+fingerprint derives the same receipt id and must not re-append.
|
|
309
|
+
if (existing.some((row) => row.receipt_id === receipt.receipt_id)) {
|
|
310
|
+
unchanged += 1;
|
|
311
|
+
if (receipt.outcome === "passed")
|
|
312
|
+
passed += 1;
|
|
313
|
+
else
|
|
314
|
+
failed += 1;
|
|
315
|
+
results.push({
|
|
316
|
+
testId,
|
|
317
|
+
outcome: receipt.outcome,
|
|
318
|
+
receiptId: receipt.receipt_id,
|
|
319
|
+
applied: false,
|
|
320
|
+
duplicate: true,
|
|
321
|
+
receiptCount: existing.length,
|
|
322
|
+
gaps: evaluation.gaps,
|
|
323
|
+
});
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
const nextReceipts = [
|
|
327
|
+
...existing,
|
|
328
|
+
receipt,
|
|
329
|
+
].slice(-MAX_PROOF_RECEIPTS);
|
|
330
|
+
const historyErrors = proofReceiptHistoryErrors(testId, test.verification_scope, nextReceipts);
|
|
331
|
+
const bindingErrors = proofReceiptCurrentBindingErrors(testId, test.verification_scope, receipt, contract, receipt.fingerprint);
|
|
332
|
+
const receiptErrors = [...historyErrors, ...bindingErrors];
|
|
333
|
+
if (receiptErrors.length > 0)
|
|
334
|
+
throw new Error(`Proof ingest failed for ${testId}: ${receiptErrors.join("; ")}`);
|
|
335
|
+
const properties = projectEntityProperties(test);
|
|
336
|
+
properties.proof_receipts = undefined;
|
|
337
|
+
// Surgical receipt append: splice only the proof_receipts block into the
|
|
338
|
+
// authored document so unrelated frontmatter keeps its authored form.
|
|
339
|
+
// Canonical re-rendering here would change non-receipt bytes, shift the
|
|
340
|
+
// workspace snapshot hash mid-campaign, and make later integrations in
|
|
341
|
+
// the same `kibi prove --all` refuse with "changed the tracked
|
|
342
|
+
// workspace". Falls back to the canonical render when the document is
|
|
343
|
+
// not a patchable markdown file.
|
|
344
|
+
let sourceDocumentOverride;
|
|
345
|
+
const source = typeof test.source === "string" ? test.source : "";
|
|
346
|
+
if (context.fs && source !== "" && /\.(md|mdx)$/i.test(source)) {
|
|
347
|
+
try {
|
|
348
|
+
const absolute = resolveContainedSourcePath(context.workspaceRoot, source);
|
|
349
|
+
const before = await context.fs.readFile(absolute);
|
|
350
|
+
sourceDocumentOverride =
|
|
351
|
+
patchReceiptsIntoDocument(before, nextReceipts) ?? undefined;
|
|
352
|
+
}
|
|
353
|
+
catch {
|
|
354
|
+
sourceDocumentOverride = undefined;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// exactOptionalPropertyTypes: only pass the override when one exists.
|
|
358
|
+
const upsertOptions = {
|
|
359
|
+
deferCompiledCommit: true,
|
|
360
|
+
...(sourceDocumentOverride === undefined
|
|
361
|
+
? {}
|
|
362
|
+
: { sourceDocumentOverride }),
|
|
363
|
+
};
|
|
364
|
+
const upsert = await executeUpsert({
|
|
365
|
+
type: "test",
|
|
366
|
+
id: testId,
|
|
367
|
+
properties: { ...properties, proof_receipts: nextReceipts },
|
|
368
|
+
}, context, upsertOptions);
|
|
369
|
+
const deferred = upsert.structuredContent?.deferredCommit;
|
|
370
|
+
if (!deferred) {
|
|
371
|
+
throw new Error(`Proof ingest failed for ${testId}: receipt commit was not prepared`);
|
|
372
|
+
}
|
|
373
|
+
pendingCommits.push({
|
|
229
374
|
testId,
|
|
230
375
|
outcome: receipt.outcome,
|
|
231
376
|
receiptId: receipt.receipt_id,
|
|
232
|
-
|
|
233
|
-
duplicate: true,
|
|
234
|
-
receiptCount: existing.length,
|
|
377
|
+
receiptCount: nextReceipts.length,
|
|
235
378
|
gaps: evaluation.gaps,
|
|
379
|
+
deferred,
|
|
236
380
|
});
|
|
237
|
-
continue;
|
|
238
381
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const absolute = resolveContainedSourcePath(context.workspaceRoot, source);
|
|
262
|
-
const before = await context.fs.readFile(absolute);
|
|
263
|
-
sourceDocumentOverride =
|
|
264
|
-
patchReceiptsIntoDocument(before, nextReceipts) ?? undefined;
|
|
265
|
-
}
|
|
266
|
-
catch {
|
|
267
|
-
sourceDocumentOverride = undefined;
|
|
382
|
+
}
|
|
383
|
+
catch (error) {
|
|
384
|
+
if (error instanceof MutationRollbackFailureError) {
|
|
385
|
+
lifecycle?.onRollbackFailure?.();
|
|
386
|
+
}
|
|
387
|
+
await rollbackUncommittedReceipts(pendingCommits, error, lifecycle);
|
|
388
|
+
}
|
|
389
|
+
const prolog = context.prolog;
|
|
390
|
+
if (!prolog)
|
|
391
|
+
throw new Error("Proof ingest failed: Prolog runtime is unavailable");
|
|
392
|
+
const batchSize = 25;
|
|
393
|
+
for (let offset = 0; offset < pendingCommits.length; offset += batchSize) {
|
|
394
|
+
const batch = pendingCommits.slice(offset, offset + batchSize);
|
|
395
|
+
let written;
|
|
396
|
+
try {
|
|
397
|
+
written = await prolog.query(buildUpsertBatchCommitGoal(batch.map((entry) => ({
|
|
398
|
+
entity: entry.deferred.entity,
|
|
399
|
+
relationships: entry.deferred.relationships,
|
|
400
|
+
skipContradictionCheck: entry.deferred.skipContradictionCheck,
|
|
401
|
+
}))));
|
|
402
|
+
if (!written.success) {
|
|
403
|
+
throw new Error(written.error || "batch commit failed");
|
|
268
404
|
}
|
|
405
|
+
// Prolog success is the irreversible commit boundary. Finalize this
|
|
406
|
+
// batch before parsing auxiliary metadata or doing more work, so later
|
|
407
|
+
// failures can only roll back still-prepared source writes.
|
|
408
|
+
for (const entry of batch)
|
|
409
|
+
entry.deferred.finalize();
|
|
410
|
+
lifecycle?.onBatchCommitted?.();
|
|
411
|
+
prolog.invalidateCache?.();
|
|
412
|
+
parseUpsertChangeKinds(written.bindings, batch.length);
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
415
|
+
await rollbackUncommittedReceipts(pendingCommits, error, lifecycle);
|
|
416
|
+
}
|
|
417
|
+
for (const entry of batch) {
|
|
418
|
+
if (entry.outcome === "passed")
|
|
419
|
+
passed += 1;
|
|
420
|
+
else
|
|
421
|
+
failed += 1;
|
|
422
|
+
results.push({
|
|
423
|
+
testId: entry.testId,
|
|
424
|
+
outcome: entry.outcome,
|
|
425
|
+
receiptId: entry.receiptId,
|
|
426
|
+
applied: true,
|
|
427
|
+
duplicate: false,
|
|
428
|
+
receiptCount: entry.receiptCount,
|
|
429
|
+
gaps: entry.gaps,
|
|
430
|
+
});
|
|
269
431
|
}
|
|
270
|
-
// exactOptionalPropertyTypes: only pass the override when one exists.
|
|
271
|
-
const upsertOptions = sourceDocumentOverride === undefined ? {} : { sourceDocumentOverride };
|
|
272
|
-
const upsert = await executeUpsert({
|
|
273
|
-
type: "test",
|
|
274
|
-
id: testId,
|
|
275
|
-
properties: { ...properties, proof_receipts: nextReceipts },
|
|
276
|
-
}, context, upsertOptions);
|
|
277
|
-
void upsert;
|
|
278
|
-
if (receipt.outcome === "passed")
|
|
279
|
-
passed += 1;
|
|
280
|
-
else
|
|
281
|
-
failed += 1;
|
|
282
|
-
results.push({
|
|
283
|
-
testId,
|
|
284
|
-
outcome: receipt.outcome,
|
|
285
|
-
receiptId: receipt.receipt_id,
|
|
286
|
-
applied: true,
|
|
287
|
-
duplicate: false,
|
|
288
|
-
receiptCount: nextReceipts.length,
|
|
289
|
-
gaps: evaluation.gaps,
|
|
290
|
-
});
|
|
291
432
|
}
|
|
292
433
|
const summary = passed > 0
|
|
293
434
|
? `Proved ${passed} test(s)${failed > 0 ? `, ${failed} failed` : ""}${unchanged > 0 ? `, ${unchanged} unchanged` : ""}.`
|
|
@@ -305,3 +446,36 @@ export async function executeIngestProof(args, context) {
|
|
|
305
446
|
},
|
|
306
447
|
};
|
|
307
448
|
}
|
|
449
|
+
export async function executeIngestProof(args, context) {
|
|
450
|
+
if (!context.fs ||
|
|
451
|
+
context.sourceFirst === false ||
|
|
452
|
+
context.sourceMutationLockHeld === true) {
|
|
453
|
+
return executeIngestProofUnlocked(args, context);
|
|
454
|
+
}
|
|
455
|
+
const lock = await acquireWorkspaceMutationLock(context.workspaceRoot);
|
|
456
|
+
let operationFailure;
|
|
457
|
+
let committed = false;
|
|
458
|
+
let releaseSafe = true;
|
|
459
|
+
try {
|
|
460
|
+
return await executeIngestProofUnlocked(args, { ...context, sourceMutationLockHeld: true }, {
|
|
461
|
+
onBatchCommitted: () => {
|
|
462
|
+
committed = true;
|
|
463
|
+
},
|
|
464
|
+
onRollbackFailure: () => {
|
|
465
|
+
releaseSafe = false;
|
|
466
|
+
},
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
catch (error) {
|
|
470
|
+
operationFailure = { error };
|
|
471
|
+
throw error;
|
|
472
|
+
}
|
|
473
|
+
finally {
|
|
474
|
+
// A failed compensation must leave the cooperative lock fail-closed. The
|
|
475
|
+
// next writer will require verified recovery rather than observing a
|
|
476
|
+
// partially restored set of receipt documents.
|
|
477
|
+
if (releaseSafe) {
|
|
478
|
+
releaseWorkspaceMutationLock(lock, operationFailure, committed);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate-legacy-receipts.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/migrate-legacy-receipts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"migrate-legacy-receipts.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/migrate-legacy-receipts.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAOjF,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,yCAAyC;IAEzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IAEjD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC/C,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AAEH,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,yBAAyB,EAC/B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IACT,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,2BAA2B,CAAC;CAChD,CAAC,CAqFD"}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
You should have received a copy of the GNU Affero General Public License
|
|
16
16
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
|
-
import { loadEntities } from "../../public/operations/discovery-entities.js";
|
|
18
|
+
import { loadEntities, loadEntitiesPaged, } from "../../public/operations/discovery-entities.js";
|
|
19
19
|
import { projectEntityProperties } from "../mutation/entity-projection.js";
|
|
20
20
|
import { resolveContainedSourcePath } from "../mutation/source-authoring.js";
|
|
21
21
|
import { executeUpsert } from "../mutation/upsert.js";
|
|
@@ -31,51 +31,57 @@ import { removeFrontmatterBlock } from "./receipt-document.js";
|
|
|
31
31
|
* the authored document and the compiled entity — one block splice, no
|
|
32
32
|
* canonical re-render.
|
|
33
33
|
*/
|
|
34
|
-
// implements REQ-kibi-
|
|
34
|
+
// implements REQ-kibi-verification-evidence-contract
|
|
35
35
|
export async function executeMigrateLegacyReceipts(args, context) {
|
|
36
36
|
if (!context.prolog)
|
|
37
37
|
throw new Error("Legacy receipt migration requires a Prolog runtime");
|
|
38
38
|
if (context.fs === undefined)
|
|
39
39
|
throw new Error("Legacy receipt migration failed: this maintenance action rewrites authored test documents and requires a filesystem-capable runtime");
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
// A bulk run pages full entities: receipt histories are exactly what this
|
|
41
|
+
// maintenance action reads, and loading all of them at once can exceed the
|
|
42
|
+
// bounded Prolog output capacity on long-lived stores.
|
|
43
|
+
const tests = args.testId === undefined
|
|
44
|
+
? await loadEntitiesPaged(context.prolog, "test")
|
|
45
|
+
: await loadEntities(context.prolog, { type: "test", id: args.testId });
|
|
44
46
|
if (args.testId !== undefined && tests.length === 0) {
|
|
45
47
|
throw new Error(`Legacy receipt migration failed: test ${args.testId} was not found`);
|
|
46
48
|
}
|
|
47
49
|
const migratedTests = [];
|
|
48
50
|
for (const test of tests) {
|
|
49
51
|
const testId = String(test.id);
|
|
50
|
-
|
|
52
|
+
// The compiled lane only survives in stores compiled by older versions:
|
|
53
|
+
// current sync does not extract verification_receipts, so the authored
|
|
54
|
+
// document is the durable carrier of the legacy block. Both signals must
|
|
55
|
+
// trigger the migration.
|
|
56
|
+
const hasCompiledLegacy = Array.isArray(test.verification_receipts);
|
|
51
57
|
const hasProofContract = test.proof_contract !== null && typeof test.proof_contract === "object";
|
|
52
|
-
if (!
|
|
58
|
+
if (!hasProofContract)
|
|
53
59
|
continue;
|
|
54
60
|
const source = typeof test.source === "string" ? test.source : "";
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
patchedContent =
|
|
60
|
-
removeFrontmatterBlock(before, "verification_receipts") ?? undefined;
|
|
61
|
-
if (patchedContent === undefined) {
|
|
62
|
-
throw new Error(`Legacy receipt migration failed for ${testId}: ${source} is not a patchable frontmatter document`);
|
|
61
|
+
const patchableSource = source !== "" && /\.(md|mdx)$/i.test(source) && context.fs !== undefined;
|
|
62
|
+
if (!patchableSource) {
|
|
63
|
+
if (hasCompiledLegacy) {
|
|
64
|
+
throw new Error(`Legacy receipt migration failed for ${testId}: test source '${source || "unknown"}' is not an authored markdown document`);
|
|
63
65
|
}
|
|
66
|
+
continue;
|
|
64
67
|
}
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
const absolute = resolveContainedSourcePath(context.workspaceRoot, source);
|
|
69
|
+
const before = await context.fs.readFile(absolute);
|
|
70
|
+
const patchedContent = removeFrontmatterBlock(before, "verification_receipts");
|
|
71
|
+
if (patchedContent === null) {
|
|
72
|
+
if (hasCompiledLegacy) {
|
|
73
|
+
throw new Error(`Legacy receipt migration failed for ${testId}: ${source} is not a patchable frontmatter document`);
|
|
74
|
+
}
|
|
75
|
+
continue;
|
|
67
76
|
}
|
|
68
77
|
const properties = Object.fromEntries(Object.entries(projectEntityProperties(test)).filter(([key]) => key !== "verification_receipts"));
|
|
69
78
|
// Drop the legacy lane from the compiled entity; proof_receipts stay
|
|
70
79
|
// untouched so append-only validation keeps holding.
|
|
71
|
-
const upsertOptions = patchedContent === undefined
|
|
72
|
-
? {}
|
|
73
|
-
: { sourceDocumentOverride: patchedContent };
|
|
74
80
|
await executeUpsert({
|
|
75
81
|
type: "test",
|
|
76
82
|
id: testId,
|
|
77
83
|
properties: { ...properties },
|
|
78
|
-
}, context,
|
|
84
|
+
}, context, { sourceDocumentOverride: patchedContent });
|
|
79
85
|
migratedTests.push({ testId });
|
|
80
86
|
}
|
|
81
87
|
const summary = migratedTests.length === 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prune-receipts.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/prune-receipts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prune-receipts.d.ts","sourceRoot":"","sources":["../../../src/operations/proof/prune-receipts.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AASjF,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,uDAAuD;IAEvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAE7C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAEzC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC3C,CAAC,CAAC;AAYH;;;;;;;;;GASG;AAEH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IACT,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,mBAAmB,CAAC;CACxC,CAAC,CAuED"}
|