kibi-cli 2.4.0 → 2.5.1
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-json-command.d.ts +6 -0
- package/dist/cli-json-command.d.ts.map +1 -1
- package/dist/cli-json-command.js +37 -9
- package/dist/cli-operation-loader.d.ts.map +1 -1
- package/dist/cli-operation-loader.js +7 -0
- package/dist/cli-operation-metadata.d.ts +12 -4
- package/dist/cli-operation-metadata.d.ts.map +1 -1
- package/dist/cli-operation-metadata.js +14 -4
- package/dist/cli-protocol.d.ts +14 -0
- package/dist/cli-protocol.d.ts.map +1 -1
- package/dist/cli-protocol.js +31 -2
- package/dist/cli-register-proof.d.ts.map +1 -1
- package/dist/cli-register-proof.js +13 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +11 -2
- package/dist/commands/discovery-shared.d.ts.map +1 -1
- package/dist/commands/discovery-shared.js +8 -2
- package/dist/commands/engine.d.ts.map +1 -1
- package/dist/commands/engine.js +4 -2
- package/dist/commands/gc.d.ts.map +1 -1
- package/dist/commands/gc.js +7 -0
- package/dist/commands/init-helpers.d.ts.map +1 -1
- package/dist/commands/init-helpers.js +38 -12
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +10 -15
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +281 -14
- package/dist/commands/proof-compact.d.ts +9 -0
- package/dist/commands/proof-compact.d.ts.map +1 -0
- package/dist/commands/proof-compact.js +58 -0
- package/dist/commands/prove.d.ts +38 -0
- package/dist/commands/prove.d.ts.map +1 -1
- package/dist/commands/prove.js +222 -47
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +61 -16
- package/dist/commands/sync.d.ts +8 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +42 -16
- package/dist/diagnostics.js +1 -1
- package/dist/engine-limits.d.ts +74 -0
- package/dist/engine-limits.d.ts.map +1 -0
- package/dist/engine-limits.js +201 -0
- package/dist/engine.d.ts +10 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +57 -9
- package/dist/extractors/manifest.d.ts +8 -0
- package/dist/extractors/manifest.d.ts.map +1 -1
- package/dist/extractors/manifest.js +34 -5
- package/dist/extractors/markdown.d.ts +8 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +57 -0
- package/dist/extractors/relationships.d.ts.map +1 -1
- package/dist/extractors/relationships.js +2 -0
- package/dist/intent-search.d.ts +4 -1
- package/dist/intent-search.d.ts.map +1 -1
- package/dist/intent-search.js +186 -33
- package/dist/operations/bootstrap/candidate-helpers.d.ts.map +1 -1
- package/dist/operations/bootstrap/candidate-helpers.js +8 -1
- package/dist/operations/bootstrap/candidates.d.ts.map +1 -1
- package/dist/operations/bootstrap/candidates.js +54 -38
- package/dist/operations/bootstrap/generate.d.ts +2 -0
- package/dist/operations/bootstrap/generate.d.ts.map +1 -1
- package/dist/operations/bootstrap/generate.js +87 -33
- package/dist/operations/bootstrap/intent-claims.d.ts.map +1 -1
- package/dist/operations/bootstrap/intent-claims.js +12 -4
- package/dist/operations/bootstrap/markdown-candidates.d.ts +2 -0
- package/dist/operations/bootstrap/markdown-candidates.d.ts.map +1 -1
- package/dist/operations/bootstrap/markdown-candidates.js +32 -10
- package/dist/operations/bootstrap/presentation.d.ts.map +1 -1
- package/dist/operations/bootstrap/presentation.js +6 -2
- package/dist/operations/bootstrap/requirement-claims.d.ts +1 -0
- package/dist/operations/bootstrap/requirement-claims.d.ts.map +1 -1
- package/dist/operations/bootstrap/requirement-claims.js +13 -1
- package/dist/operations/bootstrap/validation.d.ts +4 -0
- package/dist/operations/bootstrap/validation.d.ts.map +1 -0
- package/dist/operations/bootstrap/validation.js +20 -0
- package/dist/operations/migration/inventory-rederive.d.ts +81 -0
- package/dist/operations/migration/inventory-rederive.d.ts.map +1 -0
- package/dist/operations/migration/inventory-rederive.js +484 -0
- package/dist/operations/migration/kb-sources.d.ts +53 -0
- package/dist/operations/migration/kb-sources.d.ts.map +1 -0
- package/dist/operations/migration/kb-sources.js +233 -0
- package/dist/operations/migration/origin-backfill.d.ts +39 -0
- package/dist/operations/migration/origin-backfill.d.ts.map +1 -0
- package/dist/operations/migration/origin-backfill.js +164 -0
- package/dist/operations/migration/polarity-values.d.ts +10 -0
- package/dist/operations/migration/polarity-values.d.ts.map +1 -0
- package/dist/operations/migration/polarity-values.js +60 -0
- package/dist/operations/migration/schema6.d.ts +59 -0
- package/dist/operations/migration/schema6.d.ts.map +1 -0
- package/dist/operations/migration/schema6.js +379 -0
- package/dist/operations/migration/source-paths.d.ts +131 -0
- package/dist/operations/migration/source-paths.d.ts.map +1 -0
- package/dist/operations/migration/source-paths.js +308 -0
- package/dist/operations/migration/superseded-closure.d.ts +54 -0
- package/dist/operations/migration/superseded-closure.d.ts.map +1 -0
- package/dist/operations/migration/superseded-closure.js +187 -0
- package/dist/operations/modeling/logic-modeling.d.ts.map +1 -1
- package/dist/operations/modeling/logic-modeling.js +3 -5
- package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
- package/dist/operations/modeling/model-requirement.js +225 -67
- package/dist/operations/mutation/contradictions.d.ts +16 -0
- package/dist/operations/mutation/contradictions.d.ts.map +1 -1
- package/dist/operations/mutation/contradictions.js +32 -0
- package/dist/operations/mutation/delete.d.ts.map +1 -1
- package/dist/operations/mutation/delete.js +15 -7
- package/dist/operations/mutation/origin.d.ts +21 -0
- package/dist/operations/mutation/origin.d.ts.map +1 -0
- package/dist/operations/mutation/origin.js +78 -0
- package/dist/operations/mutation/plan-apply-journal.d.ts +182 -0
- package/dist/operations/mutation/plan-apply-journal.d.ts.map +1 -0
- package/dist/operations/mutation/plan-apply-journal.js +613 -0
- package/dist/operations/mutation/predicate-vocabulary-guard.d.ts +3 -1
- package/dist/operations/mutation/predicate-vocabulary-guard.d.ts.map +1 -1
- package/dist/operations/mutation/predicate-vocabulary-guard.js +13 -2
- package/dist/operations/mutation/relationships.d.ts +5 -5
- package/dist/operations/mutation/relationships.d.ts.map +1 -1
- package/dist/operations/mutation/relationships.js +31 -11
- package/dist/operations/mutation/serialization.d.ts.map +1 -1
- package/dist/operations/mutation/serialization.js +3 -1
- 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 +7 -1
- package/dist/operations/mutation/types.d.ts +14 -0
- package/dist/operations/mutation/types.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.d.ts +30 -3
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +105 -35
- package/dist/operations/mutation/validate-upsert.d.ts +6 -0
- package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
- package/dist/operations/mutation/validate-upsert.js +34 -30
- package/dist/operations/planning/apply-plan.d.ts.map +1 -1
- package/dist/operations/planning/apply-plan.js +753 -145
- package/dist/operations/planning/compile-intent.d.ts +34 -1
- package/dist/operations/planning/compile-intent.d.ts.map +1 -1
- package/dist/operations/planning/compile-intent.js +314 -98
- package/dist/operations/proof/code-scope.d.ts +28 -0
- package/dist/operations/proof/code-scope.d.ts.map +1 -1
- package/dist/operations/proof/code-scope.js +72 -0
- package/dist/operations/proof/compact-receipts.d.ts +49 -0
- package/dist/operations/proof/compact-receipts.d.ts.map +1 -0
- package/dist/operations/proof/compact-receipts.js +160 -0
- package/dist/operations/proof/ingest-proof.d.ts +2 -0
- package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
- package/dist/operations/proof/ingest-proof.js +44 -23
- package/dist/operations/proof/prune-receipts.d.ts.map +1 -1
- package/dist/operations/proof/prune-receipts.js +5 -9
- package/dist/operations/proof/receipt-compaction.d.ts +48 -0
- package/dist/operations/proof/receipt-compaction.d.ts.map +1 -0
- package/dist/operations/proof/receipt-compaction.js +121 -0
- package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analysis-receipt.js +12 -1
- package/dist/operations/semantic-advisor/analyze-prose.d.ts +2 -1
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +51 -5
- 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 +11 -1
- package/dist/operations/semantic-advisor/conditional-rules.d.ts +33 -0
- package/dist/operations/semantic-advisor/conditional-rules.d.ts.map +1 -0
- package/dist/operations/semantic-advisor/conditional-rules.js +262 -0
- package/dist/operations/semantic-advisor/ingestion-boundary.d.ts +3 -1
- package/dist/operations/semantic-advisor/ingestion-boundary.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/ingestion-boundary.js +14 -6
- package/dist/operations/semantic-advisor/plugin-orchestration.js +1 -1
- package/dist/prolog/codec.d.ts.map +1 -1
- package/dist/prolog/codec.js +2 -1
- package/dist/prolog.d.ts +9 -0
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +56 -10
- package/dist/proof/command-test-report.d.ts +74 -0
- package/dist/proof/command-test-report.d.ts.map +1 -0
- package/dist/proof/command-test-report.js +206 -0
- package/dist/public/branch-resolver.d.ts +1 -0
- package/dist/public/branch-resolver.d.ts.map +1 -1
- package/dist/public/branch-resolver.js +1 -0
- package/dist/public/entity-origin.d.ts +69 -0
- package/dist/public/entity-origin.d.ts.map +1 -0
- package/dist/public/entity-origin.js +142 -0
- package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
- package/dist/public/impact/full-kb-quality.js +1 -0
- package/dist/public/impact/requirement-quality.js +1 -1
- package/dist/public/operations/catalog.d.ts +130 -19
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/catalog.js +3 -0
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +8 -0
- package/dist/public/operations/contracts.d.ts +0 -5
- package/dist/public/operations/contracts.d.ts.map +1 -1
- package/dist/public/operations/contracts.js +63 -14
- package/dist/public/operations/discovery-entities.d.ts +15 -0
- package/dist/public/operations/discovery-entities.d.ts.map +1 -1
- package/dist/public/operations/discovery-entities.js +59 -0
- package/dist/public/operations/discovery-executors.d.ts +6 -1
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +65 -6
- package/dist/public/operations/index.d.ts +1 -0
- package/dist/public/operations/index.d.ts.map +1 -1
- package/dist/public/operations/index.js +1 -0
- package/dist/public/operations/migration-plan.d.ts +5 -0
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +26 -1
- package/dist/public/operations/node-ports.d.ts.map +1 -1
- package/dist/public/operations/node-ports.js +24 -3
- package/dist/public/operations/origin-review.d.ts +51 -0
- package/dist/public/operations/origin-review.d.ts.map +1 -0
- package/dist/public/operations/origin-review.js +307 -0
- package/dist/public/operations/predicate-schema-conformance.js +1 -1
- package/dist/public/operations/repair-plan.d.ts.map +1 -1
- package/dist/public/operations/repair-plan.js +4 -0
- package/dist/public/operations/result-envelope.d.ts.map +1 -1
- package/dist/public/operations/result-envelope.js +17 -5
- package/dist/public/operations/runtime-types.d.ts +9 -0
- package/dist/public/operations/runtime-types.d.ts.map +1 -1
- package/dist/public/operations/schema6-check-actions.d.ts +127 -0
- package/dist/public/operations/schema6-check-actions.d.ts.map +1 -0
- package/dist/public/operations/schema6-check-actions.js +575 -0
- package/dist/public/operations/source-path-dangling.d.ts +17 -0
- package/dist/public/operations/source-path-dangling.d.ts.map +1 -0
- package/dist/public/operations/source-path-dangling.js +66 -0
- 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 +15 -1
- package/dist/public/operations/specs/check.d.ts +2 -2
- package/dist/public/operations/specs/check.js +1 -1
- package/dist/public/operations/specs/composite.d.ts +351 -0
- package/dist/public/operations/specs/composite.d.ts.map +1 -0
- package/dist/public/operations/specs/composite.js +96 -0
- package/dist/public/operations/specs/discovery.d.ts +8 -3
- package/dist/public/operations/specs/discovery.d.ts.map +1 -1
- package/dist/public/operations/specs/discovery.js +8 -3
- package/dist/public/operations/specs/modeling.d.ts +2 -2
- package/dist/public/operations/specs/modeling.js +2 -2
- package/dist/public/operations/specs/mutation-schemas.d.ts +73 -8
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +43 -7
- package/dist/public/operations/specs/mutation.d.ts +1 -1
- package/dist/public/operations/specs/mutation.js +1 -1
- package/dist/public/operations/specs/planning.d.ts +2 -2
- package/dist/public/operations/specs/planning.js +4 -4
- package/dist/public/operations/specs/reporting.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.js +13 -26
- package/dist/public/operations/specs/upsert.d.ts +79 -9
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/operations/specs/upsert.js +6 -1
- package/dist/public/operations/types.d.ts +1 -1
- package/dist/public/operations/types.d.ts.map +1 -1
- package/dist/public/proof-receipt.d.ts +1 -0
- package/dist/public/proof-receipt.d.ts.map +1 -1
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +52 -0
- package/dist/public/schemas/relationship.d.ts.map +1 -1
- package/dist/public/schemas/relationship.js +2 -0
- package/dist/public/skills/kibi-bootstrap/SKILL.md +35 -67
- package/dist/public/skills/kibi-bootstrap/resources/bootstrap.md +6 -0
- package/dist/public/skills/kibi-usage/SKILL.md +68 -18
- package/dist/public/skills/kibi-usage/resources/fact-lanes.md +5 -5
- package/dist/public/skills/kibi-usage/resources/kb-improvement.md +1 -1
- package/dist/public/skills/kibi-usage/resources/logic-ir.md +2 -2
- package/dist/public/skills/kibi-usage/resources/operation-access.md +25 -1
- package/dist/public/skills/kibi-usage/resources/ui-requirements.md +4 -4
- package/dist/public/skills/kibi-usage/resources/workflows.md +42 -25
- package/dist/public/telemetry-acceptance.d.ts +58 -2
- package/dist/public/telemetry-acceptance.d.ts.map +1 -1
- package/dist/public/telemetry-acceptance.js +136 -10
- package/dist/public/telemetry-remediation.d.ts.map +1 -1
- package/dist/public/telemetry-remediation.js +26 -10
- package/dist/relationships/shards.d.ts +13 -0
- package/dist/relationships/shards.d.ts.map +1 -1
- package/dist/relationships/shards.js +54 -28
- package/dist/runtime/cli-runtime.d.ts.map +1 -1
- package/dist/runtime/cli-runtime.js +44 -3
- package/dist/runtime/detached-snapshot.d.ts +38 -0
- package/dist/runtime/detached-snapshot.d.ts.map +1 -0
- package/dist/runtime/detached-snapshot.js +92 -0
- package/dist/schemas/entity.schema.json +122 -0
- package/dist/search-answer.d.ts +157 -0
- package/dist/search-answer.d.ts.map +1 -0
- package/dist/search-answer.js +846 -0
- package/dist/traceability/impact-knowledge.d.ts.map +1 -1
- package/dist/traceability/impact-knowledge.js +7 -0
- package/dist/traceability/symbol-extract.js +3 -3
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +12 -0
- package/dist/types/entities.d.ts +13 -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/branch-resolver.d.ts +37 -1
- package/dist/utils/branch-resolver.d.ts.map +1 -1
- package/dist/utils/branch-resolver.js +130 -3
- package/dist/utils/repo-relative-path.d.ts +18 -0
- package/dist/utils/repo-relative-path.d.ts.map +1 -0
- package/dist/utils/repo-relative-path.js +58 -0
- package/dist/utils/rule-registry.generated.d.ts +75 -3
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +89 -3
- package/dist/utils/schema-version.d.ts +1 -1
- package/dist/utils/schema-version.d.ts.map +1 -1
- package/dist/utils/schema-version.js +4 -3
- package/dist/utils/strict-modeling.d.ts +1 -1
- package/dist/utils/strict-modeling.d.ts.map +1 -1
- package/dist/utils/strict-modeling.js +23 -3
- package/package.json +3 -3
- package/schema/entities.pl +22 -0
- package/schema/relationships.pl +14 -0
- package/schema/validation.pl +45 -1
- package/src/public/branch-resolver.ts +1 -0
- package/src/public/entity-origin.ts +175 -0
- package/src/public/impact/full-kb-quality.ts +1 -0
- package/src/public/impact/requirement-quality.ts +1 -1
- package/src/public/operations/catalog.ts +3 -0
- package/src/public/operations/check-executor.ts +15 -0
- package/src/public/operations/contracts.ts +75 -15
- package/src/public/operations/discovery-entities.ts +74 -0
- package/src/public/operations/discovery-executors.ts +88 -10
- package/src/public/operations/index.ts +1 -0
- package/src/public/operations/migration-plan.ts +30 -1
- package/src/public/operations/node-ports.ts +24 -3
- package/src/public/operations/origin-review.ts +375 -0
- package/src/public/operations/predicate-schema-conformance.ts +1 -1
- package/src/public/operations/repair-plan.ts +4 -0
- package/src/public/operations/result-envelope.ts +18 -6
- package/src/public/operations/runtime-types.ts +9 -0
- package/src/public/operations/schema6-check-actions.ts +699 -0
- package/src/public/operations/source-path-dangling.ts +81 -0
- package/src/public/operations/specs/check-rules.generated.ts +15 -1
- package/src/public/operations/specs/check.ts +1 -1
- package/src/public/operations/specs/composite.ts +141 -0
- package/src/public/operations/specs/discovery.ts +9 -3
- package/src/public/operations/specs/modeling.ts +2 -2
- package/src/public/operations/specs/mutation-schemas.ts +49 -7
- package/src/public/operations/specs/mutation.ts +1 -1
- package/src/public/operations/specs/planning.ts +4 -4
- package/src/public/operations/specs/reporting.ts +13 -38
- package/src/public/operations/specs/upsert.ts +7 -1
- package/src/public/operations/types.ts +2 -0
- package/src/public/proof-receipt.ts +1 -0
- package/src/public/schemas/entity.ts +57 -0
- package/src/public/schemas/relationship.ts +2 -0
- package/src/public/skills/kibi-bootstrap/SKILL.md +35 -67
- package/src/public/skills/kibi-bootstrap/resources/bootstrap.md +6 -0
- package/src/public/skills/kibi-usage/SKILL.md +68 -18
- package/src/public/skills/kibi-usage/resources/fact-lanes.md +5 -5
- package/src/public/skills/kibi-usage/resources/kb-improvement.md +1 -1
- package/src/public/skills/kibi-usage/resources/logic-ir.md +2 -2
- package/src/public/skills/kibi-usage/resources/operation-access.md +25 -1
- package/src/public/skills/kibi-usage/resources/ui-requirements.md +4 -4
- package/src/public/skills/kibi-usage/resources/workflows.md +42 -25
- package/src/public/telemetry-acceptance-types.d.ts +4 -1
- package/src/public/telemetry-acceptance.ts +204 -10
- package/src/public/telemetry-remediation.ts +39 -10
- package/src/schemas/entity.schema.json +122 -0
- package/src/schemas/relationship.schema.json +2 -0
package/dist/commands/prove.js
CHANGED
|
@@ -2,6 +2,7 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { executeIngestProof } from "../operations/proof/ingest-proof.js";
|
|
5
|
+
import { PROOF_TEST_REPORT_ENV, PROOF_TEST_REPORT_VERSION, attributeCommandRun, proofTestReportPath, } from "../proof/command-test-report.js";
|
|
5
6
|
import { PROOF_RUNS_DIR, loadProofIntegrations, resolveIntegration, } from "../proof/integrations.js";
|
|
6
7
|
import { convertJUnitXml } from "../proof/producers/junit-adapter.js";
|
|
7
8
|
import { convertTap } from "../proof/producers/tap-adapter.js";
|
|
@@ -273,6 +274,7 @@ export async function proveCommand(options, deps = {}) {
|
|
|
273
274
|
const runsDir = path.join(context.workspaceRoot, PROOF_RUNS_DIR);
|
|
274
275
|
await mkdir(runsDir, { recursive: true });
|
|
275
276
|
const ingestResults = [];
|
|
277
|
+
const runAttribution = new Map();
|
|
276
278
|
const failures = [];
|
|
277
279
|
for (const [integrationId, tests] of groups) {
|
|
278
280
|
const integration = resolveIntegration(integrations.integrations, integrationId);
|
|
@@ -285,7 +287,17 @@ export async function proveCommand(options, deps = {}) {
|
|
|
285
287
|
path.join(PROOF_RUNS_DIR, `${integrationId}.json`));
|
|
286
288
|
await mkdir(path.dirname(artifactPath), { recursive: true });
|
|
287
289
|
await rm(artifactPath, { force: true });
|
|
288
|
-
const
|
|
290
|
+
const selectedTestIds = tests.map((test) => String(test.id));
|
|
291
|
+
// Command integrations may attribute their run per test; any report
|
|
292
|
+
// left by an earlier run must never be read as this run's evidence.
|
|
293
|
+
const testReportPath = integration.producer === "command"
|
|
294
|
+
? proofTestReportPath(artifactPath)
|
|
295
|
+
: undefined;
|
|
296
|
+
if (testReportPath !== undefined)
|
|
297
|
+
await rm(testReportPath, { force: true });
|
|
298
|
+
const env = commandEnvironment(integration, commandArgv, snapshot, context.workspaceRoot, selectedTestIds, artifactPath);
|
|
299
|
+
if (testReportPath !== undefined)
|
|
300
|
+
env[PROOF_TEST_REPORT_ENV] = testReportPath;
|
|
289
301
|
const startedAt = new Date().toISOString();
|
|
290
302
|
let exitCode;
|
|
291
303
|
try {
|
|
@@ -296,41 +308,78 @@ export async function proveCommand(options, deps = {}) {
|
|
|
296
308
|
continue;
|
|
297
309
|
}
|
|
298
310
|
const finishedAt = new Date().toISOString();
|
|
299
|
-
let
|
|
311
|
+
let evaluated;
|
|
300
312
|
try {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
313
|
+
evaluated =
|
|
314
|
+
testReportPath === undefined
|
|
315
|
+
? {
|
|
316
|
+
artifacts: [
|
|
317
|
+
{
|
|
318
|
+
artifact: await buildArtifact({
|
|
319
|
+
integration,
|
|
320
|
+
commandArgv,
|
|
321
|
+
exitCode,
|
|
322
|
+
startedAt,
|
|
323
|
+
finishedAt,
|
|
324
|
+
artifactPath,
|
|
325
|
+
snapshot,
|
|
326
|
+
tests,
|
|
327
|
+
}),
|
|
328
|
+
testIds: selectedTestIds,
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
}
|
|
332
|
+
: buildCommandRunArtifacts({
|
|
333
|
+
integration,
|
|
334
|
+
commandArgv,
|
|
335
|
+
exitCode,
|
|
336
|
+
startedAt,
|
|
337
|
+
finishedAt,
|
|
338
|
+
snapshot,
|
|
339
|
+
tests,
|
|
340
|
+
attribution: await readCommandAttribution(testReportPath, selectedTestIds, exitCode),
|
|
341
|
+
});
|
|
311
342
|
}
|
|
312
343
|
catch (error) {
|
|
313
344
|
failures.push(`integration '${integrationId}': ${error instanceof Error ? error.message : String(error)}`);
|
|
314
345
|
continue;
|
|
315
346
|
}
|
|
316
|
-
const artifactErrors =
|
|
347
|
+
const artifactErrors = [
|
|
348
|
+
...(evaluated.wholeRun === undefined ? [] : [evaluated.wholeRun]),
|
|
349
|
+
...evaluated.artifacts.map((entry) => entry.artifact),
|
|
350
|
+
].flatMap((artifact) => proofRunArtifactErrors(artifact));
|
|
317
351
|
if (artifactErrors.length > 0) {
|
|
318
352
|
failures.push(`integration '${integrationId}' produced an invalid kibi.proof-run.v1 artifact: ${artifactErrors.join("; ")}`);
|
|
319
353
|
continue;
|
|
320
354
|
}
|
|
321
355
|
await mkdir(path.dirname(artifactPath), { recursive: true });
|
|
322
|
-
await writeFile(artifactPath, `${JSON.stringify(artifact, null, 2)}\n`, "utf8");
|
|
356
|
+
await writeFile(artifactPath, `${JSON.stringify(evaluated.wholeRun ?? evaluated.artifacts[0]?.artifact, null, 2)}\n`, "utf8");
|
|
357
|
+
if (evaluated.wholeRun !== undefined) {
|
|
358
|
+
for (const entry of evaluated.artifacts) {
|
|
359
|
+
await writeFile(partitionArtifactPath(artifactPath, entry.artifact.run.outcome), `${JSON.stringify(entry.artifact, null, 2)}\n`, "utf8");
|
|
360
|
+
}
|
|
361
|
+
}
|
|
323
362
|
const afterRun = await readWorkspaceSnapshot(context);
|
|
324
363
|
if (!afterRun.available || afterRun.snapshot.hash !== snapshot) {
|
|
325
364
|
failures.push(`integration '${integrationId}' changed the tracked workspace during proof execution; proof is bound to snapshot ${snapshot}${describeWorkspaceDrift(afterRun)}`);
|
|
326
365
|
continue;
|
|
327
366
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
367
|
+
// One ingest per partition: each test is evaluated only against the
|
|
368
|
+
// slice of the run its own steps produced.
|
|
369
|
+
const partitionResults = [];
|
|
370
|
+
for (const entry of evaluated.artifacts) {
|
|
371
|
+
const ingested = await ingestProof({
|
|
372
|
+
snapshot,
|
|
373
|
+
artifact: entry.artifact,
|
|
374
|
+
testIds: entry.testIds,
|
|
375
|
+
}, context);
|
|
376
|
+
partitionResults.push(ingested.structuredContent);
|
|
377
|
+
}
|
|
378
|
+
const merged = mergeIngestResults(partitionResults);
|
|
379
|
+
if (merged !== undefined) {
|
|
380
|
+
ingestResults.push(merged);
|
|
381
|
+
runAttribution.set(merged, evaluated);
|
|
382
|
+
}
|
|
334
383
|
const afterIngest = await readWorkspaceSnapshot(context);
|
|
335
384
|
if (!afterIngest.available || afterIngest.snapshot.hash !== snapshot) {
|
|
336
385
|
failures.push(`the tracked workspace changed while receipts were applied; re-run kibi prove${describeWorkspaceDrift(afterIngest)}`);
|
|
@@ -343,11 +392,25 @@ export async function proveCommand(options, deps = {}) {
|
|
|
343
392
|
proved: passed,
|
|
344
393
|
failed,
|
|
345
394
|
unchanged,
|
|
346
|
-
runs: ingestResults.map((result) =>
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
395
|
+
runs: ingestResults.map((result) => {
|
|
396
|
+
const attribution = runAttribution.get(result)?.attribution;
|
|
397
|
+
return {
|
|
398
|
+
integration: result.integration,
|
|
399
|
+
summary: summarize(result),
|
|
400
|
+
...(attribution === undefined
|
|
401
|
+
? {}
|
|
402
|
+
: {
|
|
403
|
+
attribution: attribution.attribution,
|
|
404
|
+
...(attribution.attribution === "aggregate"
|
|
405
|
+
? { attributionReason: attribution.reason }
|
|
406
|
+
: {}),
|
|
407
|
+
...(attribution.failedSteps.length > 0
|
|
408
|
+
? { failedSteps: attribution.failedSteps }
|
|
409
|
+
: {}),
|
|
410
|
+
}),
|
|
411
|
+
results: result.results,
|
|
412
|
+
};
|
|
413
|
+
}),
|
|
351
414
|
...(failures.length > 0 ? { failures } : {}),
|
|
352
415
|
};
|
|
353
416
|
process.stdout.write(`${JSON.stringify(summary)}\n`);
|
|
@@ -361,6 +424,138 @@ export async function proveCommand(options, deps = {}) {
|
|
|
361
424
|
: { status: "error", error: 1 });
|
|
362
425
|
}
|
|
363
426
|
}
|
|
427
|
+
/** Read a command integration's optional per-test report and attribute it. */
|
|
428
|
+
// implements REQ-kibi-fresh-verification-receipts-v2
|
|
429
|
+
export async function readCommandAttribution(reportPath, selectedTestIds, exitCode) {
|
|
430
|
+
let raw;
|
|
431
|
+
try {
|
|
432
|
+
raw = await readFile(reportPath, "utf8");
|
|
433
|
+
}
|
|
434
|
+
catch {
|
|
435
|
+
return attributeCommandRun({
|
|
436
|
+
selectedTestIds,
|
|
437
|
+
exitCode,
|
|
438
|
+
report: undefined,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
let report;
|
|
442
|
+
try {
|
|
443
|
+
report = JSON.parse(raw);
|
|
444
|
+
}
|
|
445
|
+
catch (error) {
|
|
446
|
+
return {
|
|
447
|
+
attribution: "aggregate",
|
|
448
|
+
reason: `the ${PROOF_TEST_REPORT_VERSION} is not valid JSON (${error instanceof Error ? error.message : String(error)}), so the run is evaluated as one unit`,
|
|
449
|
+
failedSteps: [],
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
return attributeCommandRun({ selectedTestIds, exitCode, report });
|
|
453
|
+
}
|
|
454
|
+
/** Where a partition's evaluated artifact is kept next to the run artifact. */
|
|
455
|
+
// implements REQ-kibi-fresh-verification-receipts-v2
|
|
456
|
+
export function partitionArtifactPath(artifactPath, outcome) {
|
|
457
|
+
const stem = artifactPath.endsWith(".json")
|
|
458
|
+
? artifactPath.slice(0, -".json".length)
|
|
459
|
+
: artifactPath;
|
|
460
|
+
return `${stem}.${outcome}.json`;
|
|
461
|
+
}
|
|
462
|
+
function describeFailedStep(step) {
|
|
463
|
+
return `${step.testId} step ${step.stepIndex} ${step.outcome}${step.exitCode === null ? "" : ` (exit ${step.exitCode})`}: ${step.command.join(" ")}`;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Build the kibi.proof-run.v1 evidence of a `command` integration run.
|
|
467
|
+
*
|
|
468
|
+
* Without per-test attribution the run is one unit, exactly as before: a
|
|
469
|
+
* failing process fails every selected test. With a valid
|
|
470
|
+
* kibi.proof-test-report.v1 the run is split into one artifact per test
|
|
471
|
+
* outcome: tests whose own steps all passed are evaluated against a passing
|
|
472
|
+
* slice (exit code 0, the aggregate result of their own steps), and each
|
|
473
|
+
* failing outcome gets a failing slice that names the steps that failed. The
|
|
474
|
+
* whole-process artifact is kept alongside for audit.
|
|
475
|
+
*/
|
|
476
|
+
// implements REQ-kibi-fresh-verification-receipts-v2
|
|
477
|
+
export function buildCommandRunArtifacts(input) {
|
|
478
|
+
const { integration, exitCode, tests, attribution } = input;
|
|
479
|
+
const base = (run, proofResults, diagnostics) => ({
|
|
480
|
+
version: PROOF_RUN_VERSION,
|
|
481
|
+
producer: {
|
|
482
|
+
name: "kibi-command-producer",
|
|
483
|
+
...(integration.producer_version !== undefined
|
|
484
|
+
? { version: integration.producer_version }
|
|
485
|
+
: {}),
|
|
486
|
+
},
|
|
487
|
+
integration: integration.id,
|
|
488
|
+
command_argv: [...input.commandArgv],
|
|
489
|
+
code_snapshot: input.snapshot,
|
|
490
|
+
environment: {
|
|
491
|
+
os: process.platform,
|
|
492
|
+
arch: process.arch,
|
|
493
|
+
runtime: { name: "node", version: process.version },
|
|
494
|
+
},
|
|
495
|
+
run,
|
|
496
|
+
proof_results: proofResults,
|
|
497
|
+
...(diagnostics.length > 0 ? { diagnostics: [...diagnostics] } : {}),
|
|
498
|
+
});
|
|
499
|
+
const timing = { started_at: input.startedAt, finished_at: input.finishedAt };
|
|
500
|
+
const allTestIds = tests.map((test) => String(test.id));
|
|
501
|
+
const wholeResults = dedupeObligations(tests);
|
|
502
|
+
const failedLines = attribution.failedSteps.map(describeFailedStep);
|
|
503
|
+
if (attribution.attribution === "aggregate") {
|
|
504
|
+
const passedRun = exitCode === 0;
|
|
505
|
+
const artifact = base({
|
|
506
|
+
outcome: passedRun ? "passed" : "failed",
|
|
507
|
+
exit_code: exitCode,
|
|
508
|
+
...timing,
|
|
509
|
+
}, passedRun ? wholeResults : markAggregateFailure(wholeResults), passedRun ? [] : [attribution.reason, ...failedLines]);
|
|
510
|
+
return {
|
|
511
|
+
artifacts: [{ artifact, testIds: allTestIds }],
|
|
512
|
+
attribution,
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
const byId = new Map(tests.map((test) => [String(test.id), test]));
|
|
516
|
+
const artifacts = attribution.partitions.map((partition) => {
|
|
517
|
+
const partitionTests = partition.testIds.map((testId) => byId.get(testId));
|
|
518
|
+
const results = dedupeObligations(partitionTests).map((result) => ({
|
|
519
|
+
...result,
|
|
520
|
+
outcome: partition.outcome,
|
|
521
|
+
}));
|
|
522
|
+
const artifact = base({
|
|
523
|
+
outcome: partition.outcome,
|
|
524
|
+
exit_code: partition.exitCode,
|
|
525
|
+
...timing,
|
|
526
|
+
...(partition.outcome === "passed"
|
|
527
|
+
? {}
|
|
528
|
+
: { failure_phase: "execution" }),
|
|
529
|
+
}, results, [
|
|
530
|
+
`per-test attribution: ${partition.testIds.length} of ${allTestIds.length} selected test(s) whose own steps ${partition.outcome === "passed" ? "all passed" : `ended ${partition.outcome}`}; the integration process exited ${exitCode}`,
|
|
531
|
+
...partition.failedSteps.map(describeFailedStep),
|
|
532
|
+
]);
|
|
533
|
+
return { artifact, testIds: partition.testIds };
|
|
534
|
+
});
|
|
535
|
+
const wholeRun = base({
|
|
536
|
+
outcome: exitCode === 0 ? "passed" : "failed",
|
|
537
|
+
exit_code: exitCode,
|
|
538
|
+
...timing,
|
|
539
|
+
}, exitCode === 0 ? wholeResults : markAggregateFailure(wholeResults), [
|
|
540
|
+
`evaluated per test: ${attribution.partitions.map((partition) => `${partition.testIds.length} ${partition.outcome}`).join(", ")}`,
|
|
541
|
+
...failedLines,
|
|
542
|
+
]);
|
|
543
|
+
return { artifacts, wholeRun, attribution };
|
|
544
|
+
}
|
|
545
|
+
function mergeIngestResults(results) {
|
|
546
|
+
const [first] = results;
|
|
547
|
+
if (first === undefined)
|
|
548
|
+
return undefined;
|
|
549
|
+
if (results.length === 1)
|
|
550
|
+
return first;
|
|
551
|
+
return {
|
|
552
|
+
...first,
|
|
553
|
+
passed: results.reduce((sum, result) => sum + result.passed, 0),
|
|
554
|
+
failed: results.reduce((sum, result) => sum + result.failed, 0),
|
|
555
|
+
unchanged: results.reduce((sum, result) => sum + result.unchanged, 0),
|
|
556
|
+
results: results.flatMap((result) => result.results),
|
|
557
|
+
};
|
|
558
|
+
}
|
|
364
559
|
async function buildArtifact(input) {
|
|
365
560
|
const { integration, commandArgv, exitCode, startedAt, finishedAt, artifactPath, snapshot, tests, } = input;
|
|
366
561
|
const run = (outcome) => ({
|
|
@@ -369,28 +564,8 @@ async function buildArtifact(input) {
|
|
|
369
564
|
started_at: startedAt,
|
|
370
565
|
finished_at: finishedAt,
|
|
371
566
|
});
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
return {
|
|
375
|
-
version: PROOF_RUN_VERSION,
|
|
376
|
-
producer: {
|
|
377
|
-
name: "kibi-command-producer",
|
|
378
|
-
...(integration.producer_version !== undefined
|
|
379
|
-
? { version: integration.producer_version }
|
|
380
|
-
: {}),
|
|
381
|
-
},
|
|
382
|
-
integration: integration.id,
|
|
383
|
-
command_argv: [...commandArgv],
|
|
384
|
-
code_snapshot: snapshot,
|
|
385
|
-
environment: {
|
|
386
|
-
os: process.platform,
|
|
387
|
-
arch: process.arch,
|
|
388
|
-
runtime: { name: "node", version: process.version },
|
|
389
|
-
},
|
|
390
|
-
run: run(exitCode === 0 ? "passed" : "failed"),
|
|
391
|
-
proof_results: exitCode === 0 ? results : markAggregateFailure(results),
|
|
392
|
-
};
|
|
393
|
-
}
|
|
567
|
+
// `command` integrations never reach this function: proveCommand builds
|
|
568
|
+
// their artifacts with buildCommandRunArtifacts (per-test attribution).
|
|
394
569
|
if (integration.producer === "junit" || integration.producer === "tap") {
|
|
395
570
|
const nativePath = integration.artifact;
|
|
396
571
|
if (!nativePath)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/persistence.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/persistence.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA2HrD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAuFD,iFAAiF;AACjF,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,0EAA0E;AAC1E,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED,8EAA8E;AAC9E,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,SAAS,qBAAqB,EAAE,GAC9C,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAmCD,wBAAsB,eAAe,CAEnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EACtB,OAAO,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAO,GAChD,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CA8QvD;AA4BD,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,MAAM,CAER;AAGD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,kBAAkB,EAAE,qBAAqB,EAAE,EAC3C,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,OAAO,CAAC;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAmO7D"}
|
|
@@ -60,6 +60,7 @@ const STRING_ARRAY_FIELDS = new Set([
|
|
|
60
60
|
"argument_names",
|
|
61
61
|
"argument_types",
|
|
62
62
|
"argument_descriptions",
|
|
63
|
+
"key_arguments",
|
|
63
64
|
"aliases",
|
|
64
65
|
"examples",
|
|
65
66
|
"predicate_args",
|
|
@@ -149,29 +150,54 @@ function parsePrologList(value) {
|
|
|
149
150
|
}
|
|
150
151
|
return values;
|
|
151
152
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
153
|
+
function sourceLookupCandidates(sourceFile) {
|
|
154
|
+
return [
|
|
155
|
+
...new Set([
|
|
156
|
+
sourceFile,
|
|
157
|
+
path.relative(process.cwd(), sourceFile),
|
|
158
|
+
path.basename(sourceFile),
|
|
159
|
+
]),
|
|
160
|
+
];
|
|
161
|
+
}
|
|
162
|
+
async function entityIdsForCandidate(prolog, candidate, ids) {
|
|
163
|
+
const result = await prolog.query(`kb_entities_by_source(${toPrologString(candidate)}, Ids)`);
|
|
164
|
+
if (result.success) {
|
|
165
|
+
for (const id of parsePrologList(result.bindings?.Ids))
|
|
166
|
+
ids.add(id);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Source lookups per round trip. One engine round trip per candidate made a
|
|
171
|
+
* cold sync of ~1,600 sources spend minutes in socket and poll latency; the
|
|
172
|
+
* lookups are pure reads, so a bounded batch returns the same id union.
|
|
173
|
+
*/
|
|
174
|
+
const SOURCE_LOOKUP_BATCH_SIZE = 200;
|
|
175
|
+
// implements REQ-core-journaled-engine-persistence
|
|
176
|
+
async function entityIdsForSources(prolog, sourceFiles) {
|
|
177
|
+
const candidates = [
|
|
178
|
+
...new Set(sourceFiles.flatMap((file) => sourceLookupCandidates(file))),
|
|
179
|
+
];
|
|
158
180
|
const ids = new Set();
|
|
159
|
-
for (
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
181
|
+
for (let offset = 0; offset < candidates.length; offset += SOURCE_LOOKUP_BATCH_SIZE) {
|
|
182
|
+
const chunk = candidates.slice(offset, offset + SOURCE_LOOKUP_BATCH_SIZE);
|
|
183
|
+
const sources = chunk.map((candidate) => toPrologString(candidate));
|
|
184
|
+
const batched = await prolog.query(`findall(Id, (member(Source, [${sources.join(",")}]), kb_entities_by_source(Source, SourceIds), member(Id, SourceIds)), Ids)`);
|
|
185
|
+
if (batched.success) {
|
|
186
|
+
for (const id of parsePrologList(batched.bindings?.Ids))
|
|
163
187
|
ids.add(id);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
// A failed batch must not hide the ids a single lookup would still find:
|
|
191
|
+
// retry this chunk one candidate at a time, as before batching.
|
|
192
|
+
for (const candidate of chunk) {
|
|
193
|
+
await entityIdsForCandidate(prolog, candidate, ids);
|
|
164
194
|
}
|
|
165
195
|
}
|
|
166
|
-
return
|
|
196
|
+
return ids;
|
|
167
197
|
}
|
|
168
198
|
/** Remove entities owned by changed/deleted source files before re-upserting. */
|
|
169
199
|
export async function retractEntitiesForSources(prolog, sourceFiles) {
|
|
170
|
-
const ids =
|
|
171
|
-
for (const sourceFile of sourceFiles) {
|
|
172
|
-
for (const id of await entityIdsForSource(prolog, sourceFile))
|
|
173
|
-
ids.add(id);
|
|
174
|
-
}
|
|
200
|
+
const ids = await entityIdsForSources(prolog, sourceFiles);
|
|
175
201
|
if (ids.size === 0)
|
|
176
202
|
return 0;
|
|
177
203
|
const goals = [...ids].map((id) => `kb_retract_entity(${toPrologAtom(id)})`);
|
|
@@ -351,9 +377,28 @@ prolog, results, entityIds, options = {}) {
|
|
|
351
377
|
if (entity.type === "req" && entity.proof_exempt !== undefined) {
|
|
352
378
|
props.push(`proof_exempt=${entity.proof_exempt}`);
|
|
353
379
|
}
|
|
380
|
+
if (entity.type === "scenario" && entity.expects !== undefined) {
|
|
381
|
+
props.push(`expects=${toPrologAtom(entity.expects)}`);
|
|
382
|
+
}
|
|
354
383
|
if (entity.type === "req" && entity.proof_exempt_reason !== undefined) {
|
|
355
384
|
props.push(`proof_exempt_reason=${toPrologString(entity.proof_exempt_reason)}`);
|
|
356
385
|
}
|
|
386
|
+
for (const field of [
|
|
387
|
+
"approved_by",
|
|
388
|
+
"approval_ref",
|
|
389
|
+
"rationale",
|
|
390
|
+
]) {
|
|
391
|
+
const value = entity.type === "req" ? entity[field] : undefined;
|
|
392
|
+
if (value !== undefined)
|
|
393
|
+
props.push(`${field}=${toPrologString(value)}`);
|
|
394
|
+
}
|
|
395
|
+
if (entity.type === "req" && entity.exempts_claims) {
|
|
396
|
+
props.push(`exempts_claims=[${entity.exempts_claims.map(toPrologAtom).join(",")}]`);
|
|
397
|
+
}
|
|
398
|
+
// Provenance travels as a JSON object string, like proof_contract.
|
|
399
|
+
if (entity.origin !== undefined) {
|
|
400
|
+
props.push(`origin=${toPrologString(JSON.stringify(entity.origin))}`);
|
|
401
|
+
}
|
|
357
402
|
if (sourceFile)
|
|
358
403
|
props.push(`sourceFile=${toPrologString(sourceFile)}`);
|
|
359
404
|
if (entity.type === "symbol") {
|
package/dist/commands/sync.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Diagnostic, SyncSummary } from "../diagnostics.js";
|
|
2
2
|
import { acquireSymbolCompilerLock } from "../operations/mutation/symbol-compiler-lock.js";
|
|
3
3
|
import { PrologProcess } from "../prolog.js";
|
|
4
|
+
import { type BranchAttachment } from "../utils/branch-resolver.js";
|
|
4
5
|
import type { PendingSourceReceiptSnapshot } from "./sync/discovery.js";
|
|
5
6
|
export declare class SyncError extends Error {
|
|
6
7
|
constructor(message: string);
|
|
@@ -42,6 +43,13 @@ export declare function syncCommand(options?: {
|
|
|
42
43
|
recoveryBackupPath?: string;
|
|
43
44
|
/** Workspace to operate on when invoked through MCP or another host. */
|
|
44
45
|
workspaceRoot?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Internal: compile the read-only snapshot of a detached checkout into
|
|
48
|
+
* the attachment from resolveReadBranchAttachment instead of a branch KB.
|
|
49
|
+
*/
|
|
50
|
+
detachedSnapshot?: BranchAttachment;
|
|
51
|
+
/** Keep stdout clean for a host's own output; stderr still reports. */
|
|
52
|
+
quiet?: boolean;
|
|
45
53
|
}, runtime?: SyncCommandRuntime): Promise<SyncResult>;
|
|
46
54
|
export { normalizeMarkdownPath } from "./sync/discovery.js";
|
|
47
55
|
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA6BjE,OAAO,EAEL,yBAAyB,EAE1B,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA6BjE,OAAO,EAEL,yBAAyB,EAE1B,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,6BAA6B,CAAC;AAyBrC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AA2BxE,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAmCD,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,4BAA4B,UAAQ,EACpC,4BAA4B,GAAE,4BAA4B,EAAO,GAChE,MAAM,EAAE,CAuGV;AAqDD,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,yBAAyB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3E,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,yBAAyB,GAAG;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,KACzD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,aAAa,CAAC;IAC/D,yBAAyB,CAAC,EAAE,OAAO,yBAAyB,CAAC;CAC9D;AA6DD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAGvE;AAGD,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,IAAI,GAChB,IAAI,CAMN;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,UAAU,EAAE,EACzB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,IAAI,CAIN;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAMP;AAED,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,UAAU,EAAE,EACzB,oBAAoB,EAAE,OAAO,EAC7B,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,GAClB,IAAI,CAUN;AAGD,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;CACZ,EACN,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CA0pCrB;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/commands/sync.js
CHANGED
|
@@ -27,7 +27,7 @@ import { acquireSymbolCompilerLock, releaseSymbolCompilerLock, } from "../operat
|
|
|
27
27
|
import { analyzeSemanticAdvisorInput } from "../operations/semantic-advisor/analyze-prose.js";
|
|
28
28
|
import { validateSemanticInventoryBoundary } from "../operations/semantic-advisor/ingestion-boundary.js";
|
|
29
29
|
import { PrologProcess } from "../prolog.js";
|
|
30
|
-
import { resolveBranchAttachment } from "../utils/branch-resolver.js";
|
|
30
|
+
import { detachedHeadWriteRefusal, resolveBranchAttachment, } from "../utils/branch-resolver.js";
|
|
31
31
|
import { branchStoreManifestPath, branchStorePath, ensureBranchStoreManifest, expectedBranchStoreManifest, } from "../utils/branch-store-locator.js";
|
|
32
32
|
import { loadEntityPaths } from "../utils/config.js";
|
|
33
33
|
import { SYNC_CACHE_TTL_MS, SYNC_CACHE_VERSION, SYNC_COMPILER_FINGERPRINT, hashFile, hashManifestWithCoordinates, hashNormalized, readSyncCache, toCacheKey, writeSyncCache, } from "./sync/cache.js";
|
|
@@ -267,6 +267,9 @@ export function maybePushDocsNotIndexedDiagnostic(diagnostics, performedFullRein
|
|
|
267
267
|
// implements REQ-003, REQ-007
|
|
268
268
|
export async function syncCommand(options = {}, runtime = {}) {
|
|
269
269
|
const validateOnly = options.validateOnly ?? false;
|
|
270
|
+
const info = options.quiet
|
|
271
|
+
? () => undefined
|
|
272
|
+
: (...args) => console.log(...args);
|
|
270
273
|
const rebuild = options.rebuild ?? false;
|
|
271
274
|
const recoveryBackupPath = options.recoveryBackupPath;
|
|
272
275
|
const workspaceRoot = path.resolve(options.workspaceRoot ?? process.cwd());
|
|
@@ -299,12 +302,21 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
299
302
|
}
|
|
300
303
|
assertNoUnresolvedGitConflicts(workspaceRoot);
|
|
301
304
|
// Branch resolution
|
|
302
|
-
|
|
305
|
+
if (options.detachedSnapshot !== undefined &&
|
|
306
|
+
options.detachedSnapshot.kind !== "detached_snapshot") {
|
|
307
|
+
throw new SyncError("Only a detached HEAD snapshot attachment can be compiled explicitly");
|
|
308
|
+
}
|
|
309
|
+
const branchResult = options.detachedSnapshot ?? resolveBranchAttachment(workspaceRoot);
|
|
303
310
|
if ("error" in branchResult) {
|
|
304
|
-
|
|
311
|
+
// A detached HEAD has no branch KB to compile; name the way out and
|
|
312
|
+
// that reads keep working from the checkout's read-only snapshot.
|
|
313
|
+
const reason = branchResult.code === "DETACHED_HEAD"
|
|
314
|
+
? detachedHeadWriteRefusal("kibi sync", workspaceRoot)
|
|
315
|
+
: branchResult.error;
|
|
316
|
+
const diagnostic = branchErrorToDiagnostic(branchResult.code, reason);
|
|
305
317
|
diagnostics.push(diagnostic);
|
|
306
|
-
console.error(`Failed to resolve active branch: ${
|
|
307
|
-
throw new SyncError(`Failed to resolve active branch: ${
|
|
318
|
+
console.error(`Failed to resolve active branch: ${reason}`);
|
|
319
|
+
throw new SyncError(`Failed to resolve active branch: ${reason}`);
|
|
308
320
|
}
|
|
309
321
|
if (branchResult.migrationRequired && !validateOnly) {
|
|
310
322
|
throw new SyncError(`Sync blocked: KB is attached through legacy branch storage for '${branchResult.gitBranch}'. Run 'kibi branch migrate --from ${branchResult.kbBranch} --to ${branchResult.gitBranch} --apply' first.`);
|
|
@@ -393,7 +405,7 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
393
405
|
compilerCacheIsFresh(syncCache, workspaceRoot, sourceFiles, nowMs) &&
|
|
394
406
|
compilerCacheFilesMatch(syncCache, workspaceRoot, sourceFiles, relationshipShardFiles, fastPathSourceHashOf)) {
|
|
395
407
|
await checkpointNoopSync(workspaceRoot, currentBranch);
|
|
396
|
-
|
|
408
|
+
info("✓ Imported 0 entities, 0 relationships (no changes)");
|
|
397
409
|
return withOptionalCommit({
|
|
398
410
|
branch: currentBranch,
|
|
399
411
|
timestamp: new Date().toISOString(),
|
|
@@ -631,6 +643,9 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
631
643
|
const results = useEntityDelta
|
|
632
644
|
? extractedResults.filter(({ entity }) => changedEntityIds.has(entity.id))
|
|
633
645
|
: extractedResults;
|
|
646
|
+
// implements REQ-kibi-proposition-complete-ingestion, REQ-cli-schema-migration
|
|
647
|
+
// Every drifted inventory is reported in one run, not one per sync attempt.
|
|
648
|
+
const inventoryFailures = [];
|
|
634
649
|
for (const result of extractedResults) {
|
|
635
650
|
if (result.entity.type !== "req")
|
|
636
651
|
continue;
|
|
@@ -654,11 +669,19 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
654
669
|
previousSemanticHash !== boundary.sourceHash) ||
|
|
655
670
|
advertisedContract;
|
|
656
671
|
if (enforceBoundary && boundary.errors.length > 0) {
|
|
657
|
-
|
|
672
|
+
inventoryFailures.push(`${key}: proposition-complete ingestion failed: ${boundary.errors.join("; ")}.`);
|
|
673
|
+
continue;
|
|
658
674
|
}
|
|
659
675
|
nextSemanticHashes[key] = boundary.sourceHash;
|
|
660
676
|
nextSemanticContracts[key] = advertisedContract;
|
|
661
677
|
}
|
|
678
|
+
if (inventoryFailures.length > 0) {
|
|
679
|
+
throw new SyncError([
|
|
680
|
+
`${inventoryFailures.length} requirement(s) failed proposition-complete ingestion:`,
|
|
681
|
+
...inventoryFailures.map((failure) => ` ${failure}`),
|
|
682
|
+
"Run 'kibi migrate' to re-derive inventories that drifted with the semantic advisor (it lists any that need a manual fix), or run kb_model mode analyze (CLI: semantic-advisor) with the complete requirement prose and preserve its inventory contract.",
|
|
683
|
+
].join("\n"));
|
|
684
|
+
}
|
|
662
685
|
// Collect INVALID_AUTHORING diagnostics
|
|
663
686
|
for (const err of errors) {
|
|
664
687
|
const error = new Error(err.message);
|
|
@@ -732,7 +755,7 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
732
755
|
semanticContracts: evictedSemanticContracts,
|
|
733
756
|
compilerFingerprint: SYNC_COMPILER_FINGERPRINT,
|
|
734
757
|
});
|
|
735
|
-
|
|
758
|
+
info("✓ Imported 0 entities, 0 relationships (no changes)");
|
|
736
759
|
return withOptionalCommit({
|
|
737
760
|
branch: currentBranch,
|
|
738
761
|
timestamp: new Date().toISOString(),
|
|
@@ -748,7 +771,7 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
748
771
|
const livePath = branchStorePath(workspaceRoot, currentBranch);
|
|
749
772
|
const kbExists = existsSync(livePath);
|
|
750
773
|
maybePushKbMissingDiagnostic(diagnostics, kbExists, rebuild, currentBranch, livePath);
|
|
751
|
-
// implements REQ-core-journaled-engine-
|
|
774
|
+
// implements REQ-core-journaled-engine-persistence
|
|
752
775
|
// Normal syncs are compiled directly into the long-lived single-writer
|
|
753
776
|
// engine. Rebuilds retain generation replacement semantics, and injected
|
|
754
777
|
// Prolog runtimes keep the staging path used by the contract fixtures.
|
|
@@ -759,6 +782,9 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
759
782
|
workspaceRoot,
|
|
760
783
|
branch: currentBranch,
|
|
761
784
|
timeout: 120_000,
|
|
785
|
+
// Compilation reads (source lookups before retracts) must finish;
|
|
786
|
+
// operator read limits are for interactive queries.
|
|
787
|
+
readLimits: null,
|
|
762
788
|
});
|
|
763
789
|
const engineProlog = engine;
|
|
764
790
|
try {
|
|
@@ -884,7 +910,7 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
884
910
|
entityCount < markdownFiles.length) {
|
|
885
911
|
diagnostics.push(createDocsNotIndexedDiagnostic(markdownFiles.length, entityCount));
|
|
886
912
|
}
|
|
887
|
-
|
|
913
|
+
info(`✓ Imported ${entityCount} entities, ${relationshipCount} relationships (removed ${removedCount} entities)`);
|
|
888
914
|
const commit = getCurrentCommit();
|
|
889
915
|
const summary = withOptionalCommit({
|
|
890
916
|
branch: currentBranch,
|
|
@@ -896,7 +922,7 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
896
922
|
failures: diagnostics,
|
|
897
923
|
durationMs: Date.now() - startTime,
|
|
898
924
|
}, commit);
|
|
899
|
-
|
|
925
|
+
info(formatSyncSummary(summary));
|
|
900
926
|
return { ...summary, exitCode: 0 };
|
|
901
927
|
}
|
|
902
928
|
finally {
|
|
@@ -980,7 +1006,7 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
980
1006
|
exitCode: 1,
|
|
981
1007
|
}, getCurrentCommit());
|
|
982
1008
|
}
|
|
983
|
-
|
|
1009
|
+
info(`OK: Validation passed (${entityCount} entities)`);
|
|
984
1010
|
return withOptionalCommit({
|
|
985
1011
|
branch: currentBranch,
|
|
986
1012
|
timestamp: new Date().toISOString(),
|
|
@@ -1073,7 +1099,7 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
1073
1099
|
});
|
|
1074
1100
|
published = true;
|
|
1075
1101
|
maybePushDocsNotIndexedDiagnostic(diagnostics, performedFullReindex, markdownFiles.length, entityCount);
|
|
1076
|
-
|
|
1102
|
+
info(`✓ Imported ${entityCount} entities, ${relationshipCount} relationships`);
|
|
1077
1103
|
const commit = getCurrentCommit();
|
|
1078
1104
|
const summary = withOptionalCommit({
|
|
1079
1105
|
branch: currentBranch,
|
|
@@ -1085,7 +1111,7 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
1085
1111
|
failures: diagnostics,
|
|
1086
1112
|
durationMs: Date.now() - startTime,
|
|
1087
1113
|
}, commit);
|
|
1088
|
-
|
|
1114
|
+
info(formatSyncSummary(summary));
|
|
1089
1115
|
return { ...summary, exitCode: 0 };
|
|
1090
1116
|
}
|
|
1091
1117
|
catch (error) {
|
|
@@ -1112,9 +1138,9 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
1112
1138
|
durationMs: Date.now() - startTime,
|
|
1113
1139
|
}, commit);
|
|
1114
1140
|
if (diagnostics.length > 0) {
|
|
1115
|
-
|
|
1141
|
+
info("\nDiagnostics:");
|
|
1116
1142
|
for (const d of diagnostics) {
|
|
1117
|
-
|
|
1143
|
+
info(` [${d.category}] ${d.severity}: ${d.message}`);
|
|
1118
1144
|
}
|
|
1119
1145
|
}
|
|
1120
1146
|
throw error;
|