kibi-cli 2.3.0 → 2.5.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-json-command.d.ts +6 -0
- package/dist/cli-json-command.d.ts.map +1 -1
- package/dist/cli-json-command.js +39 -11
- 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 +13 -5
- package/dist/cli-operation-metadata.d.ts.map +1 -1
- package/dist/cli-operation-metadata.js +15 -5
- 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-maintenance.d.ts.map +1 -1
- package/dist/cli-register-maintenance.js +7 -0
- 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 +0 -1
- package/dist/commands/merge-driver.d.ts +31 -0
- package/dist/commands/merge-driver.d.ts.map +1 -0
- package/dist/commands/merge-driver.js +268 -0
- 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 +55 -39
- package/dist/operations/bootstrap/discovery.js +1 -1
- 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 +107 -37
- package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
- package/dist/operations/bootstrap/guidance-actions.js +3 -0
- package/dist/operations/bootstrap/guidance.d.ts.map +1 -1
- package/dist/operations/bootstrap/guidance.js +7 -1
- package/dist/operations/bootstrap/intent-claims.d.ts +17 -0
- package/dist/operations/bootstrap/intent-claims.d.ts.map +1 -0
- package/dist/operations/bootstrap/intent-claims.js +103 -0
- 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 +2 -0
- package/dist/operations/bootstrap/presentation.d.ts.map +1 -1
- package/dist/operations/bootstrap/presentation.js +66 -3
- 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/types.d.ts +28 -0
- package/dist/operations/bootstrap/types.d.ts.map +1 -1
- package/dist/operations/bootstrap/types.js +16 -0
- 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/symbol-refresh.d.ts.map +1 -1
- package/dist/operations/mutation/symbol-refresh.js +4 -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 +751 -144
- 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/diagnostic-usage.d.ts +14 -0
- package/dist/public/diagnostic-usage.d.ts.map +1 -1
- package/dist/public/diagnostic-usage.js +55 -1
- 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 +203 -20
- 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/bootstrap.d.ts +73 -1
- package/dist/public/operations/specs/bootstrap.d.ts.map +1 -1
- package/dist/public/operations/specs/bootstrap.js +66 -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 +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/symbol-repair-plan.d.ts.map +1 -1
- package/dist/public/operations/symbol-repair-plan.js +3 -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 +52 -11
- package/dist/public/skills/kibi-bootstrap/resources/bootstrap.md +12 -1
- package/dist/public/skills/kibi-usage/SKILL.md +82 -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 +29 -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 +64 -0
- package/dist/public/telemetry-acceptance.d.ts.map +1 -1
- package/dist/public/telemetry-acceptance.js +143 -7
- 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/diagnostic-usage.ts +59 -1
- 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/bootstrap.ts +78 -4
- 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/symbol-repair-plan.ts +3 -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 +52 -11
- package/src/public/skills/kibi-bootstrap/resources/bootstrap.md +12 -1
- package/src/public/skills/kibi-usage/SKILL.md +82 -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 +29 -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 +210 -7
- package/src/public/telemetry-remediation.ts +39 -10
- package/src/schemas/entity.schema.json +122 -0
- package/src/schemas/relationship.schema.json +2 -0
|
@@ -7,6 +7,10 @@ import {
|
|
|
7
7
|
getSchemaVersionStatus,
|
|
8
8
|
normalizeSchemaVersion,
|
|
9
9
|
} from "../../utils/schema-version.js";
|
|
10
|
+
import {
|
|
11
|
+
lifecycleActionsFromViolations,
|
|
12
|
+
schema6ReviewActionsFromCheck,
|
|
13
|
+
} from "./schema6-check-actions.js";
|
|
10
14
|
|
|
11
15
|
export const MIGRATION_PLAN_VERSION = "kibi.migration-plan.v2" as const;
|
|
12
16
|
|
|
@@ -286,6 +290,25 @@ export function mergeMigrationPlans(
|
|
|
286
290
|
});
|
|
287
291
|
}
|
|
288
292
|
|
|
293
|
+
/**
|
|
294
|
+
* The same plan without the actions whose code another planner owns, e.g.
|
|
295
|
+
* lifecycle repairs `kibi migrate` plans from authored sources.
|
|
296
|
+
*/
|
|
297
|
+
// implements REQ-agent-guided-migration-orchestration
|
|
298
|
+
export function withoutActionCodes(
|
|
299
|
+
plan: MigrationPlan,
|
|
300
|
+
codes: ReadonlySet<string>,
|
|
301
|
+
): MigrationPlan {
|
|
302
|
+
if (!plan.actions.some((action) => codes.has(action.code))) return plan;
|
|
303
|
+
return buildMigrationPlan({
|
|
304
|
+
expected: plan.expected,
|
|
305
|
+
evaluatedDomains: plan.scope.evaluatedDomains,
|
|
306
|
+
incompleteDomains: plan.scope.incompleteDomains,
|
|
307
|
+
actions: plan.actions.filter((action) => !codes.has(action.code)),
|
|
308
|
+
diagnostics: plan.diagnostics,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
289
312
|
function actionDefaults(input: Partial<MigrationAction>): MigrationAction {
|
|
290
313
|
return {
|
|
291
314
|
id: input.id ?? "migration-action-unknown",
|
|
@@ -370,13 +393,16 @@ function predicateSchemaAlignmentAction(
|
|
|
370
393
|
/** Migration code for mechanical predicate namespace/alias repairs. */
|
|
371
394
|
export const PREDICATE_SCHEMA_ALIGNMENT_CODE = "predicate_schema_alignment";
|
|
372
395
|
|
|
373
|
-
// implements REQ-agent-guided-migration-orchestration, REQ-kibi-predicate-vocabulary-migration
|
|
396
|
+
// implements REQ-agent-guided-migration-orchestration, REQ-kibi-predicate-vocabulary-migration, REQ-cli-schema-migration
|
|
374
397
|
export function buildActionsFromCheck(input: {
|
|
375
398
|
violations?: readonly Readonly<Record<string, unknown>>[];
|
|
376
399
|
qualityDiagnostics?: readonly Readonly<Record<string, unknown>>[];
|
|
377
400
|
}): MigrationAction[] {
|
|
378
401
|
const actions: MigrationAction[] = [];
|
|
402
|
+
const lifecycle = lifecycleActionsFromViolations(input.violations ?? []);
|
|
403
|
+
actions.push(...lifecycle.actions.map(migrationAction));
|
|
379
404
|
for (const [index, violation] of (input.violations ?? []).entries()) {
|
|
405
|
+
if (lifecycle.consumed.has(index)) continue;
|
|
380
406
|
const rule = typeof violation.rule === "string" ? violation.rule : "check";
|
|
381
407
|
const entityId =
|
|
382
408
|
typeof violation.entityId === "string" ? violation.entityId : "";
|
|
@@ -399,9 +425,12 @@ export function buildActionsFromCheck(input: {
|
|
|
399
425
|
}),
|
|
400
426
|
);
|
|
401
427
|
}
|
|
428
|
+
const reviews = schema6ReviewActionsFromCheck(input.qualityDiagnostics ?? []);
|
|
429
|
+
actions.push(...reviews.actions.map(migrationAction));
|
|
402
430
|
for (const [index, diagnostic] of (
|
|
403
431
|
input.qualityDiagnostics ?? []
|
|
404
432
|
).entries()) {
|
|
433
|
+
if (reviews.consumed.has(index)) continue;
|
|
405
434
|
const id = typeof diagnostic.id === "string" ? diagnostic.id : "quality";
|
|
406
435
|
const entityId =
|
|
407
436
|
typeof diagnostic.entityId === "string" ? diagnostic.entityId : "";
|
|
@@ -101,19 +101,26 @@ async function workspaceSnapshot(workspaceRoot: string) {
|
|
|
101
101
|
],
|
|
102
102
|
{ encoding: "buffer", maxBuffer: 64 * 1024 * 1024 },
|
|
103
103
|
);
|
|
104
|
+
// The snapshot names each file by its repo-relative path in Unicode NFC, so
|
|
105
|
+
// a checkout whose filesystem reports decomposed names (macOS) hashes the
|
|
106
|
+
// same commit to the same snapshot as a Linux CI runner. The raw name is
|
|
107
|
+
// kept only to read the file.
|
|
104
108
|
const paths = listed
|
|
105
109
|
.toString("utf8")
|
|
106
110
|
.split("\0")
|
|
107
111
|
.filter(Boolean)
|
|
108
112
|
.filter(includedSnapshotPath)
|
|
109
|
-
.
|
|
113
|
+
.map((raw) => ({ raw, key: raw.normalize("NFC") }))
|
|
114
|
+
.sort((left, right) =>
|
|
115
|
+
left.key < right.key ? -1 : left.key > right.key ? 1 : 0,
|
|
116
|
+
);
|
|
110
117
|
const digest = createHash("sha256");
|
|
111
118
|
digest.update("kibi.workspace-snapshot.v2\0");
|
|
112
|
-
for (const relativePath of paths) {
|
|
119
|
+
for (const { raw, key: relativePath } of paths) {
|
|
113
120
|
digest.update(relativePath);
|
|
114
121
|
digest.update("\0");
|
|
115
122
|
try {
|
|
116
|
-
const content = await fs.readFile(path.join(workspaceRoot,
|
|
123
|
+
const content = await fs.readFile(path.join(workspaceRoot, raw));
|
|
117
124
|
digest.update(snapshotFileContent(relativePath, content));
|
|
118
125
|
} catch (error) {
|
|
119
126
|
const code =
|
|
@@ -188,6 +195,20 @@ export const nodeFilesystem: NodeFilesystemPort = {
|
|
|
188
195
|
},
|
|
189
196
|
stat: (filePath) => fs.stat(filePath),
|
|
190
197
|
unlink: (filePath) => fs.unlink(filePath),
|
|
198
|
+
fsync: async (filePath) => {
|
|
199
|
+
// Windows cannot open a directory handle; directory entries are durable
|
|
200
|
+
// there once the rename returns.
|
|
201
|
+
if (process.platform === "win32") {
|
|
202
|
+
const stat = await fs.stat(filePath);
|
|
203
|
+
if (stat.isDirectory()) return;
|
|
204
|
+
}
|
|
205
|
+
const handle = await fs.open(filePath, "r");
|
|
206
|
+
try {
|
|
207
|
+
await handle.sync();
|
|
208
|
+
} finally {
|
|
209
|
+
await handle.close();
|
|
210
|
+
}
|
|
211
|
+
},
|
|
191
212
|
glob: (patterns, options) =>
|
|
192
213
|
fg([...patterns], {
|
|
193
214
|
cwd: options.cwd,
|
|
@@ -0,0 +1,375 @@
|
|
|
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
|
+
This program is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Affero General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { readFileSync } from "node:fs";
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
import { parseListOfLists, parsePrologValue } from "../../prolog/codec.js";
|
|
22
|
+
import type { Violation } from "../../utils/rule-registry.js";
|
|
23
|
+
import { readEntityOrigin } from "../entity-origin.js";
|
|
24
|
+
import { loadEntitiesPaged } from "./discovery-entities.js";
|
|
25
|
+
import type { PrologPort } from "./runtime-types.js";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Advisory review of who approved what. Kibi cannot verify that a person
|
|
29
|
+
* approved anything; these rules make agent-recorded approvals and
|
|
30
|
+
* agent-authored requirements visible so a human can confirm them.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/** An exception without approved_by exempts nothing. */
|
|
34
|
+
// implements REQ-kibi-entity-origin
|
|
35
|
+
export const EXCEPTION_UNAPPROVED_RULE = "exception-unapproved";
|
|
36
|
+
/** An agent recorded an exception approval without human corroboration. */
|
|
37
|
+
// implements REQ-kibi-entity-origin
|
|
38
|
+
export const EXCEPTION_APPROVAL_SELF_ATTESTED_RULE =
|
|
39
|
+
"exception-approval-self-attested";
|
|
40
|
+
/** Agent-authored requirements no human has approved yet. */
|
|
41
|
+
// implements REQ-kibi-entity-origin
|
|
42
|
+
export const AGENT_REQUIREMENT_UNAPPROVED_RULE = "agent-requirement-unapproved";
|
|
43
|
+
/** A human- or agent-authored requirement that records no reason. */
|
|
44
|
+
// implements REQ-core-validation-rules
|
|
45
|
+
export const REQUIREMENT_RATIONALE_MISSING_RULE =
|
|
46
|
+
"requirement-rationale-missing";
|
|
47
|
+
|
|
48
|
+
// implements REQ-kibi-entity-origin
|
|
49
|
+
export const ORIGIN_REVIEW_RULES = [
|
|
50
|
+
EXCEPTION_UNAPPROVED_RULE,
|
|
51
|
+
EXCEPTION_APPROVAL_SELF_ATTESTED_RULE,
|
|
52
|
+
AGENT_REQUIREMENT_UNAPPROVED_RULE,
|
|
53
|
+
REQUIREMENT_RATIONALE_MISSING_RULE,
|
|
54
|
+
] as const;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Origins whose author could have said why. Imported, inferred and legacy
|
|
58
|
+
* requirements were transcribed from somewhere else; their reason lives
|
|
59
|
+
* with the original, so requirement-rationale-missing does not ask for it.
|
|
60
|
+
*/
|
|
61
|
+
const RATIONALE_ORIGIN_KINDS = new Set(["human", "agent"]);
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* agent-requirement-unapproved lists at most this many requirements (sorted
|
|
65
|
+
* by id) and then one summary finding, so a large agent-authored KB yields a
|
|
66
|
+
* bounded review queue instead of one warning per requirement.
|
|
67
|
+
*/
|
|
68
|
+
// implements REQ-kibi-entity-origin
|
|
69
|
+
export const AGENT_REQUIREMENT_REVIEW_LIMIT = 25;
|
|
70
|
+
|
|
71
|
+
const CURRENT_REQUIREMENT_STATUSES = new Set([
|
|
72
|
+
"open",
|
|
73
|
+
"in_progress",
|
|
74
|
+
"closed",
|
|
75
|
+
"active",
|
|
76
|
+
"approved",
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
type Entity = Readonly<Record<string, unknown>>;
|
|
80
|
+
|
|
81
|
+
// implements REQ-kibi-entity-origin
|
|
82
|
+
export type OriginReviewInput = Readonly<{
|
|
83
|
+
requirements: readonly Entity[];
|
|
84
|
+
/** `[exception, base]` pairs of `exempts` relationships. */
|
|
85
|
+
exempts: readonly (readonly [string, string])[];
|
|
86
|
+
/** Requirements some other requirement supersedes. */
|
|
87
|
+
superseded: ReadonlySet<string>;
|
|
88
|
+
/** Requirements linked to an ADR (either direction, any typed edge). */
|
|
89
|
+
adrLinked?: ReadonlySet<string>;
|
|
90
|
+
/** Whether the requirement's document has a Rationale or Why section. */
|
|
91
|
+
hasRationaleSection?: (entity: Entity) => boolean;
|
|
92
|
+
}>;
|
|
93
|
+
|
|
94
|
+
const RATIONALE_HEADING = /^#{1,6}[ \t]+(?:rationale|why)\b/im;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* True when a Markdown document (frontmatter ignored) has a heading that
|
|
98
|
+
* starts with "Rationale" or "Why", at any level.
|
|
99
|
+
*/
|
|
100
|
+
// implements REQ-kibi-entity-origin
|
|
101
|
+
export function markdownHasRationaleSection(content: string): boolean {
|
|
102
|
+
const body = content.startsWith("---")
|
|
103
|
+
? content.replace(/^---\r?\n[\s\S]*?\r?\n---[ \t]*(?:\r?\n|$)/, "")
|
|
104
|
+
: content;
|
|
105
|
+
return RATIONALE_HEADING.test(body);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Read each requirement's own document (its compiled `source`) at most once
|
|
110
|
+
* and report whether it has a Rationale or Why section. Unreadable files
|
|
111
|
+
* count as having none.
|
|
112
|
+
*/
|
|
113
|
+
// implements REQ-kibi-entity-origin
|
|
114
|
+
export function rationaleSectionReader(
|
|
115
|
+
workspaceRoot: string,
|
|
116
|
+
): (entity: Entity) => boolean {
|
|
117
|
+
const cache = new Map<string, boolean>();
|
|
118
|
+
return (entity) => {
|
|
119
|
+
const source = text(entity.source);
|
|
120
|
+
if (source === undefined || !source.endsWith(".md")) return false;
|
|
121
|
+
const file = path.resolve(workspaceRoot, source);
|
|
122
|
+
const cached = cache.get(file);
|
|
123
|
+
if (cached !== undefined) return cached;
|
|
124
|
+
let found = false;
|
|
125
|
+
try {
|
|
126
|
+
found = markdownHasRationaleSection(readFileSync(file, "utf8"));
|
|
127
|
+
} catch {
|
|
128
|
+
found = false;
|
|
129
|
+
}
|
|
130
|
+
cache.set(file, found);
|
|
131
|
+
return found;
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function text(value: unknown): string | undefined {
|
|
136
|
+
return typeof value === "string" && value.trim() !== ""
|
|
137
|
+
? value.trim()
|
|
138
|
+
: undefined;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function sourceField(entity: Entity): { source?: string } {
|
|
142
|
+
const source = text(entity.source);
|
|
143
|
+
return source !== undefined ? { source } : {};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function isCurrent(entity: Entity, superseded: ReadonlySet<string>): boolean {
|
|
147
|
+
const status = text(entity.status);
|
|
148
|
+
return (
|
|
149
|
+
status !== undefined &&
|
|
150
|
+
CURRENT_REQUIREMENT_STATUSES.has(status) &&
|
|
151
|
+
!superseded.has(String(entity.id))
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Evaluate the origin review rules over loaded requirements. */
|
|
156
|
+
// implements REQ-kibi-entity-origin
|
|
157
|
+
export function evaluateOriginReview(
|
|
158
|
+
input: OriginReviewInput,
|
|
159
|
+
rules: ReadonlySet<string> = new Set(ORIGIN_REVIEW_RULES),
|
|
160
|
+
): Violation[] {
|
|
161
|
+
const byId = new Map(
|
|
162
|
+
input.requirements.map((entity) => [String(entity.id), entity]),
|
|
163
|
+
);
|
|
164
|
+
const current = [...byId.values()]
|
|
165
|
+
.filter((entity) => isCurrent(entity, input.superseded))
|
|
166
|
+
.sort((left, right) => String(left.id).localeCompare(String(right.id)));
|
|
167
|
+
const exempted = new Map<string, string[]>();
|
|
168
|
+
for (const [exception, base] of input.exempts) {
|
|
169
|
+
exempted.set(exception, [...(exempted.get(exception) ?? []), base]);
|
|
170
|
+
}
|
|
171
|
+
const findings: Violation[] = [];
|
|
172
|
+
|
|
173
|
+
for (const entity of current) {
|
|
174
|
+
const id = String(entity.id);
|
|
175
|
+
const bases = [...new Set(exempted.get(id) ?? [])].sort();
|
|
176
|
+
if (bases.length === 0) continue;
|
|
177
|
+
const approvedBy = text(entity.approved_by);
|
|
178
|
+
const approvalRef = text(entity.approval_ref);
|
|
179
|
+
const origin = readEntityOrigin(entity.origin);
|
|
180
|
+
if (approvedBy === undefined) {
|
|
181
|
+
if (!rules.has(EXCEPTION_UNAPPROVED_RULE)) continue;
|
|
182
|
+
findings.push({
|
|
183
|
+
rule: EXCEPTION_UNAPPROVED_RULE,
|
|
184
|
+
entityId: id,
|
|
185
|
+
description: `Exception ${id} exempts ${bases.join(", ")} but has no approved_by, so it exempts nothing: success scenarios it specifies are still checked against ${bases.join(", ")}`,
|
|
186
|
+
suggestion: `Have a human decide: set approved_by (and approval_ref to the decision record) on ${id} if the exception is approved, or remove the exempts link and set expects: rejection on the scenario if it is not`,
|
|
187
|
+
...sourceField(entity),
|
|
188
|
+
evidence: { exceptionId: id, exempts: bases },
|
|
189
|
+
});
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (
|
|
193
|
+
!rules.has(EXCEPTION_APPROVAL_SELF_ATTESTED_RULE) ||
|
|
194
|
+
origin?.kind !== "agent"
|
|
195
|
+
) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const missing = [
|
|
199
|
+
...(origin.approved_by === undefined ? ["origin.approved_by"] : []),
|
|
200
|
+
...(approvalRef === undefined ? ["approval_ref"] : []),
|
|
201
|
+
];
|
|
202
|
+
if (missing.length === 0) continue;
|
|
203
|
+
findings.push({
|
|
204
|
+
rule: EXCEPTION_APPROVAL_SELF_ATTESTED_RULE,
|
|
205
|
+
entityId: id,
|
|
206
|
+
description: `Exception ${id} was recorded by an agent with approved_by '${approvedBy}', but nothing corroborates the approval (missing ${missing.join(" and ")})`,
|
|
207
|
+
suggestion: `Have ${approvedBy} (or another human) confirm the exception: set origin.approved_by to the confirming person and approval_ref to the decision record (ticket, ADR or review link) on ${id}; if nobody approved it, remove approved_by so the exception stops exempting ${bases.join(", ")}`,
|
|
208
|
+
...sourceField(entity),
|
|
209
|
+
evidence: {
|
|
210
|
+
exceptionId: id,
|
|
211
|
+
exempts: bases,
|
|
212
|
+
approvedBy,
|
|
213
|
+
origin,
|
|
214
|
+
missing,
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (rules.has(AGENT_REQUIREMENT_UNAPPROVED_RULE)) {
|
|
220
|
+
const unreviewed = current.filter((entity) => {
|
|
221
|
+
const origin = readEntityOrigin(entity.origin);
|
|
222
|
+
return origin?.kind === "agent" && origin.approved_by === undefined;
|
|
223
|
+
});
|
|
224
|
+
for (const entity of unreviewed.slice(0, AGENT_REQUIREMENT_REVIEW_LIMIT)) {
|
|
225
|
+
const origin = readEntityOrigin(entity.origin);
|
|
226
|
+
findings.push({
|
|
227
|
+
rule: AGENT_REQUIREMENT_UNAPPROVED_RULE,
|
|
228
|
+
entityId: String(entity.id),
|
|
229
|
+
description: `Requirement ${String(entity.id)} was authored by an agent${origin?.ref !== undefined ? ` (${origin.ref})` : ""} and no human has approved it`,
|
|
230
|
+
suggestion:
|
|
231
|
+
"Review the requirement text; when it states the intended behavior, record the reviewer in origin.approved_by (keep kind: agent and the rest of origin)",
|
|
232
|
+
...sourceField(entity),
|
|
233
|
+
evidence: { origin },
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
const remaining = unreviewed.length - AGENT_REQUIREMENT_REVIEW_LIMIT;
|
|
237
|
+
if (remaining > 0) {
|
|
238
|
+
findings.push({
|
|
239
|
+
rule: AGENT_REQUIREMENT_UNAPPROVED_RULE,
|
|
240
|
+
entityId: "workspace",
|
|
241
|
+
description: `${remaining} more agent-authored requirement(s) have no human approval; the list above stops at ${AGENT_REQUIREMENT_REVIEW_LIMIT}`,
|
|
242
|
+
suggestion:
|
|
243
|
+
"Approve the listed requirements first; the next kb_check lists the following ones",
|
|
244
|
+
evidence: {
|
|
245
|
+
total: unreviewed.length,
|
|
246
|
+
listed: AGENT_REQUIREMENT_REVIEW_LIMIT,
|
|
247
|
+
remainingIds: unreviewed
|
|
248
|
+
.slice(AGENT_REQUIREMENT_REVIEW_LIMIT)
|
|
249
|
+
.map((entity) => String(entity.id)),
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (rules.has(REQUIREMENT_RATIONALE_MISSING_RULE)) {
|
|
256
|
+
findings.push(...rationaleFindings(current, input));
|
|
257
|
+
}
|
|
258
|
+
return findings;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* requirement-rationale-missing: a requirement a person or agent wrote
|
|
263
|
+
* (origin kind human or agent) with no `rationale`, no Rationale/Why
|
|
264
|
+
* section and no ADR link. Capped like agent-requirement-unapproved.
|
|
265
|
+
*/
|
|
266
|
+
function rationaleFindings(
|
|
267
|
+
current: readonly Entity[],
|
|
268
|
+
input: OriginReviewInput,
|
|
269
|
+
): Violation[] {
|
|
270
|
+
const adrLinked = input.adrLinked ?? new Set<string>();
|
|
271
|
+
const missing = current.filter((entity) => {
|
|
272
|
+
const origin = readEntityOrigin(entity.origin);
|
|
273
|
+
if (origin === null || !RATIONALE_ORIGIN_KINDS.has(origin.kind)) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
if (text(entity.rationale) !== undefined) return false;
|
|
277
|
+
if (adrLinked.has(String(entity.id))) return false;
|
|
278
|
+
return input.hasRationaleSection?.(entity) !== true;
|
|
279
|
+
});
|
|
280
|
+
const findings: Violation[] = missing
|
|
281
|
+
.slice(0, AGENT_REQUIREMENT_REVIEW_LIMIT)
|
|
282
|
+
.map((entity) => ({
|
|
283
|
+
rule: REQUIREMENT_RATIONALE_MISSING_RULE,
|
|
284
|
+
entityId: String(entity.id),
|
|
285
|
+
description: `Requirement ${String(entity.id)} does not say why it exists: it has no rationale field, no Rationale or Why section and no linked ADR`,
|
|
286
|
+
suggestion:
|
|
287
|
+
"Ask the person who stated the intent why it matters and record the answer in rationale (one or two sentences), or link the ADR that explains the decision",
|
|
288
|
+
...sourceField(entity),
|
|
289
|
+
evidence: { origin: readEntityOrigin(entity.origin) },
|
|
290
|
+
}));
|
|
291
|
+
const remaining = missing.length - AGENT_REQUIREMENT_REVIEW_LIMIT;
|
|
292
|
+
if (remaining > 0) {
|
|
293
|
+
findings.push({
|
|
294
|
+
rule: REQUIREMENT_RATIONALE_MISSING_RULE,
|
|
295
|
+
entityId: "workspace",
|
|
296
|
+
description: `${remaining} more requirement(s) do not say why they exist; the list above stops at ${AGENT_REQUIREMENT_REVIEW_LIMIT}`,
|
|
297
|
+
suggestion:
|
|
298
|
+
"Record the rationale of the listed requirements first; the next kb_check lists the following ones",
|
|
299
|
+
evidence: {
|
|
300
|
+
total: missing.length,
|
|
301
|
+
listed: AGENT_REQUIREMENT_REVIEW_LIMIT,
|
|
302
|
+
remainingIds: missing
|
|
303
|
+
.slice(AGENT_REQUIREMENT_REVIEW_LIMIT)
|
|
304
|
+
.map((entity) => String(entity.id)),
|
|
305
|
+
},
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
return findings;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* `[type, from, to]` rows the review reads, in one query: every `exempts` and
|
|
313
|
+
* `supersedes` edge, plus `[adr_link, Req, Adr]` for each requirement linked
|
|
314
|
+
* with an ADR by any typed edge in either direction.
|
|
315
|
+
*/
|
|
316
|
+
async function reviewRelationships(
|
|
317
|
+
prolog: Pick<PrologPort, "query">,
|
|
318
|
+
): Promise<Array<[string, string, string]>> {
|
|
319
|
+
const result = await prolog.query(
|
|
320
|
+
"findall([Type,From,To], ((member(Type, [exempts, supersedes]), kb_relationship(Type, From, To)) ; (Type = adr_link, kb_entity(To, adr, _), kibi_relationships:relationship_type(Rel), (kb_relationship(Rel, To, From) ; kb_relationship(Rel, From, To)), kb_entity(From, req, _))), Rows)",
|
|
321
|
+
);
|
|
322
|
+
if (!result.success) {
|
|
323
|
+
throw new Error(
|
|
324
|
+
`Unable to read exempts, supersedes and ADR relationships: ${result.error ?? "query failed"}`,
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
return parseListOfLists(result.bindings.Rows ?? "[]").map(
|
|
328
|
+
([type, from, to]) =>
|
|
329
|
+
[
|
|
330
|
+
String(parsePrologValue(type ?? "")),
|
|
331
|
+
String(parsePrologValue(from ?? "")),
|
|
332
|
+
String(parsePrologValue(to ?? "")),
|
|
333
|
+
] as [string, string, string],
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** Load requirements and relationships once and evaluate the selected rules. */
|
|
338
|
+
// implements REQ-kibi-entity-origin
|
|
339
|
+
export async function collectOriginReviewViolations(
|
|
340
|
+
prolog: Pick<PrologPort, "query">,
|
|
341
|
+
rules: ReadonlySet<string>,
|
|
342
|
+
workspaceRoot?: string,
|
|
343
|
+
): Promise<Violation[]> {
|
|
344
|
+
if (!ORIGIN_REVIEW_RULES.some((rule) => rules.has(rule))) return [];
|
|
345
|
+
// One Prolog port serves queries in order; read sequentially.
|
|
346
|
+
const requirements = await loadEntitiesPaged(prolog, "req");
|
|
347
|
+
const relationships = await reviewRelationships(prolog);
|
|
348
|
+
const rationale = rules.has(REQUIREMENT_RATIONALE_MISSING_RULE)
|
|
349
|
+
? {
|
|
350
|
+
adrLinked: new Set(
|
|
351
|
+
relationships
|
|
352
|
+
.filter(([type]) => type === "adr_link")
|
|
353
|
+
.map(([, from]) => from),
|
|
354
|
+
),
|
|
355
|
+
...(workspaceRoot !== undefined
|
|
356
|
+
? { hasRationaleSection: rationaleSectionReader(workspaceRoot) }
|
|
357
|
+
: {}),
|
|
358
|
+
}
|
|
359
|
+
: {};
|
|
360
|
+
return evaluateOriginReview(
|
|
361
|
+
{
|
|
362
|
+
requirements,
|
|
363
|
+
exempts: relationships
|
|
364
|
+
.filter(([type]) => type === "exempts")
|
|
365
|
+
.map(([, from, to]) => [from, to] as const),
|
|
366
|
+
superseded: new Set(
|
|
367
|
+
relationships
|
|
368
|
+
.filter(([type]) => type === "supersedes")
|
|
369
|
+
.map(([, , to]) => to),
|
|
370
|
+
),
|
|
371
|
+
...rationale,
|
|
372
|
+
},
|
|
373
|
+
rules,
|
|
374
|
+
);
|
|
375
|
+
}
|
|
@@ -349,7 +349,7 @@ function conformanceSuggestion(evidence: PredicateConformanceEvidence): string {
|
|
|
349
349
|
if (evidence.candidateNamespaces.length > 1) {
|
|
350
350
|
return "Set predicate_namespace to the schema this claim belongs to.";
|
|
351
351
|
}
|
|
352
|
-
return "Declare a predicate_schema for this signature (
|
|
352
|
+
return "Declare a predicate_schema for this signature (kb_model mode predicates helps pick an existing one) or move the claim to a schema that already exists.";
|
|
353
353
|
}
|
|
354
354
|
|
|
355
355
|
/** Load every fact once and evaluate predicate conformance. */
|
|
@@ -204,6 +204,8 @@ const GAP_PHASE: Readonly<Record<string, RepairPhase>> = {
|
|
|
204
204
|
logic_manifest_mismatch: "manifest_links",
|
|
205
205
|
blocking_contradiction: "contradiction_resolution",
|
|
206
206
|
missing_scenario: "scenario_endpoints",
|
|
207
|
+
infeasible_scenario: "scenario_endpoints",
|
|
208
|
+
unknown_scenario_feasibility: "scenario_endpoints",
|
|
207
209
|
missing_scenario_test: "scenario_tests",
|
|
208
210
|
proof_snapshot_unavailable: "snapshot_runtime",
|
|
209
211
|
missing_passing_e2e: "proof_evidence",
|
|
@@ -231,6 +233,8 @@ const GAP_STAGE: Readonly<Record<string, string>> = {
|
|
|
231
233
|
blocking_contradiction: "contradictions",
|
|
232
234
|
contradiction_check_incomplete: "contradictions",
|
|
233
235
|
missing_scenario: "scenarios",
|
|
236
|
+
infeasible_scenario: "scenarios",
|
|
237
|
+
unknown_scenario_feasibility: "scenarios",
|
|
234
238
|
missing_scenario_test: "scenario_tests",
|
|
235
239
|
missing_passing_e2e: "passing_e2e",
|
|
236
240
|
missing_proof_receipt: "passing_e2e",
|
|
@@ -158,11 +158,23 @@ export function toKibiResult<T>(
|
|
|
158
158
|
} = {},
|
|
159
159
|
): KibiResult<T> {
|
|
160
160
|
const row = record(data) ? data : undefined;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
161
|
+
let status = options.status;
|
|
162
|
+
if (!status) {
|
|
163
|
+
status = "success";
|
|
164
|
+
if (row?.status === "committed_with_repairs")
|
|
165
|
+
status = "committed_with_repairs";
|
|
166
|
+
if (row?.status === "rejected") status = "error";
|
|
167
|
+
}
|
|
168
|
+
const terminalError =
|
|
169
|
+
row?.status === "rejected"
|
|
170
|
+
? {
|
|
171
|
+
code: "BOOTSTRAP_PLAN_REJECTED",
|
|
172
|
+
message:
|
|
173
|
+
"Bootstrap stopped at a deterministic failure. Inspect actionResults for committed actions and re-plan from the current state.",
|
|
174
|
+
retryable: false,
|
|
175
|
+
}
|
|
176
|
+
: undefined;
|
|
177
|
+
const resultError = options.error ?? terminalError;
|
|
166
178
|
const outcome = effectOutcome(status, options);
|
|
167
179
|
return {
|
|
168
180
|
kibiProtocol: KIBI_PROTOCOL_VERSION,
|
|
@@ -176,7 +188,7 @@ export function toKibiResult<T>(
|
|
|
176
188
|
],
|
|
177
189
|
diagnostics: options.diagnostics ?? diagnostics(row?.diagnostics),
|
|
178
190
|
nextActions: options.nextActions ?? nextActions(row?.nextActions),
|
|
179
|
-
...(
|
|
191
|
+
...(resultError ? { error: resultError } : {}),
|
|
180
192
|
};
|
|
181
193
|
}
|
|
182
194
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EngineLimitExceeded } from "../../engine-limits.js";
|
|
1
2
|
import type { CapabilityRegistry } from "../../plugins/registry.js";
|
|
2
3
|
import type { PrologErrorRecord } from "../../prolog/error-terms.js";
|
|
3
4
|
import type { BranchAttachment } from "../../utils/branch-resolver.js";
|
|
@@ -19,6 +20,8 @@ export type PrologQueryResult = {
|
|
|
19
20
|
readonly error?: string;
|
|
20
21
|
/** Structured error term when the failure crossed a kb.pl throw site. */
|
|
21
22
|
readonly errorRecord?: PrologErrorRecord;
|
|
23
|
+
/** Set when the engine stopped a bounded read at its limit. */
|
|
24
|
+
readonly limitExceeded?: EngineLimitExceeded;
|
|
22
25
|
};
|
|
23
26
|
|
|
24
27
|
export type PrologEntityQueryInput = Readonly<{
|
|
@@ -146,6 +149,12 @@ export interface FilesystemPort {
|
|
|
146
149
|
stat(path: string): Promise<FilesystemStat>;
|
|
147
150
|
/** Optional destructive primitive used only to roll back newly-created files. */
|
|
148
151
|
unlink?(path: string): Promise<void>;
|
|
152
|
+
/**
|
|
153
|
+
* Flush a file's (or directory's) contents to stable storage when the host
|
|
154
|
+
* supports it. Atomic plan application calls it on staged files before the
|
|
155
|
+
* rename that publishes them.
|
|
156
|
+
*/
|
|
157
|
+
fsync?(path: string): Promise<void>;
|
|
149
158
|
}
|
|
150
159
|
|
|
151
160
|
export interface GitPort {
|