kibi-runtime 2.13.1 → 2.13.2
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/engine-daemon.js
CHANGED
|
@@ -102,7 +102,7 @@ function manifestVersion(manifestPath, expectedName) {
|
|
|
102
102
|
}
|
|
103
103
|
function cliVersion() {
|
|
104
104
|
if (true)
|
|
105
|
-
return "2.
|
|
105
|
+
return "2.17.0";
|
|
106
106
|
return manifestVersion(path.join(moduleDirectory, "..", "package.json"), "kibi-cli") ?? "unknown";
|
|
107
107
|
}
|
|
108
108
|
function coreVersion() {
|
package/dist/index.js
CHANGED
|
@@ -6757,7 +6757,7 @@ function manifestVersion(manifestPath, expectedName) {
|
|
|
6757
6757
|
}
|
|
6758
6758
|
function cliVersion() {
|
|
6759
6759
|
if (true)
|
|
6760
|
-
return "2.
|
|
6760
|
+
return "2.17.0";
|
|
6761
6761
|
return manifestVersion(path2.join(moduleDirectory, "..", "package.json"), "kibi-cli") ?? "unknown";
|
|
6762
6762
|
}
|
|
6763
6763
|
function coreVersion() {
|
|
@@ -13780,7 +13780,7 @@ async function executeStatus(_input, context) {
|
|
|
13780
13780
|
const enrichedPayload = {
|
|
13781
13781
|
...payload,
|
|
13782
13782
|
...compilerReason ? { syncState: "stale", dirty: true } : {},
|
|
13783
|
-
...storeUncompiled
|
|
13783
|
+
...storeUncompiled ? { syncState: "stale", dirty: true } : {},
|
|
13784
13784
|
branchAttachment: attachment,
|
|
13785
13785
|
branchStore: store,
|
|
13786
13786
|
...engineStatus ? { engineStatus } : {},
|
|
@@ -14087,10 +14087,21 @@ function sourceOf(payload) {
|
|
|
14087
14087
|
function normalizeKey(value) {
|
|
14088
14088
|
return value.trim().toLowerCase().replace(/['’]/g, "").replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
14089
14089
|
}
|
|
14090
|
-
function
|
|
14091
|
-
if (
|
|
14090
|
+
function singularizeToken(value, keep = []) {
|
|
14091
|
+
if (value.length <= 3 || keep.includes(value))
|
|
14092
|
+
return value;
|
|
14093
|
+
if (value.endsWith("ies") && value.length > 4) {
|
|
14094
|
+
return `${value.slice(0, -3)}y`;
|
|
14095
|
+
}
|
|
14096
|
+
if (ES_PLURAL_SUFFIXES.some((suffix) => value.endsWith(suffix))) {
|
|
14097
|
+
return value.slice(0, -2);
|
|
14098
|
+
}
|
|
14099
|
+
if (!value.endsWith("s") || /(?:ss|us|is)$/.test(value))
|
|
14092
14100
|
return value;
|
|
14093
|
-
return value.
|
|
14101
|
+
return value.slice(0, -1);
|
|
14102
|
+
}
|
|
14103
|
+
function singularize(value) {
|
|
14104
|
+
return singularizeToken(value, ["status", "results"]);
|
|
14094
14105
|
}
|
|
14095
14106
|
function normalizeSubjectKey(value) {
|
|
14096
14107
|
return normalizeKey(value).split("_").map(singularize).join(".");
|
|
@@ -14220,9 +14231,10 @@ function predicateSuggestion(payload, evidence, name, args, rationale, polarity
|
|
|
14220
14231
|
} : null
|
|
14221
14232
|
};
|
|
14222
14233
|
}
|
|
14223
|
-
var SEMANTIC_INVENTORY_VERSION = "kibi.semantic-inventory.v1";
|
|
14234
|
+
var SEMANTIC_INVENTORY_VERSION = "kibi.semantic-inventory.v1", ES_PLURAL_SUFFIXES;
|
|
14224
14235
|
var init_shared = __esm(() => {
|
|
14225
14236
|
init_clauses();
|
|
14237
|
+
ES_PLURAL_SUFFIXES = ["ches", "shes", "sses", "xes"];
|
|
14226
14238
|
});
|
|
14227
14239
|
|
|
14228
14240
|
// ../cli/dist/operations/semantic-advisor/ingestion-boundary.js
|
|
@@ -43374,13 +43386,34 @@ function coverageForRequirement(result, manifestResults, entities) {
|
|
|
43374
43386
|
scenarioTests
|
|
43375
43387
|
};
|
|
43376
43388
|
}
|
|
43389
|
+
function supersededRequirementIds(manifestResults) {
|
|
43390
|
+
return new Set(manifestResults.flatMap((result) => result.entity.type === "req" ? result.relationships.flatMap((relationship) => relationship.type === "supersedes" ? [relationship.to] : []) : []));
|
|
43391
|
+
}
|
|
43392
|
+
function isReviewableRequirement(requirement, superseded) {
|
|
43393
|
+
if (superseded.has(requirement.id))
|
|
43394
|
+
return false;
|
|
43395
|
+
const status = requirement.status.trim().toLowerCase();
|
|
43396
|
+
if (REVIEWED_REQUIREMENT_STATUSES.has(status))
|
|
43397
|
+
return true;
|
|
43398
|
+
return status === "closed" && (requirement.tags ?? []).includes("implemented");
|
|
43399
|
+
}
|
|
43377
43400
|
function createCoverageDepthQualityDiagnostics(manifestResults, proofByRequirement = new Map) {
|
|
43378
43401
|
const entities = entitiesById(manifestResults);
|
|
43379
|
-
|
|
43402
|
+
const superseded = supersededRequirementIds(manifestResults);
|
|
43403
|
+
return manifestResults.filter((result) => result.entity.type === "req" && isReviewableRequirement(result.entity, superseded)).flatMap((result) => {
|
|
43380
43404
|
const diagnostic = createDiagnostic(coverageForRequirement(result, manifestResults, entities), proofByRequirement.get(result.entity.id));
|
|
43381
43405
|
return diagnostic === undefined ? [] : [diagnostic];
|
|
43382
43406
|
}).toSorted((left, right) => (left.entityId ?? "").localeCompare(right.entityId ?? ""));
|
|
43383
43407
|
}
|
|
43408
|
+
var REVIEWED_REQUIREMENT_STATUSES;
|
|
43409
|
+
var init_coverage_depth_quality = __esm(() => {
|
|
43410
|
+
REVIEWED_REQUIREMENT_STATUSES = new Set([
|
|
43411
|
+
"open",
|
|
43412
|
+
"in_progress",
|
|
43413
|
+
"active",
|
|
43414
|
+
"approved"
|
|
43415
|
+
]);
|
|
43416
|
+
});
|
|
43384
43417
|
|
|
43385
43418
|
// ../cli/dist/public/impact/requirement-quality.js
|
|
43386
43419
|
function isRequirement2(result) {
|
|
@@ -44053,6 +44086,7 @@ var init_full_kb_quality = __esm(() => {
|
|
|
44053
44086
|
init_proof_receipt();
|
|
44054
44087
|
init_relationship();
|
|
44055
44088
|
init_telemetry_acceptance();
|
|
44089
|
+
init_coverage_depth_quality();
|
|
44056
44090
|
init_requirement_quality();
|
|
44057
44091
|
init_symbol_quality();
|
|
44058
44092
|
RELATIONSHIP_TYPES = relationship_default.properties.type.enum;
|
|
@@ -55597,9 +55631,7 @@ function normalizePredicateToken(value) {
|
|
|
55597
55631
|
return value.trim().replace(/\b(?:a|an|the)\b\s*/gi, "").replace(/['’]/g, "").replace(/\s+/g, "_").replace(/[^A-Za-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "");
|
|
55598
55632
|
}
|
|
55599
55633
|
function singularize2(value) {
|
|
55600
|
-
|
|
55601
|
-
return value;
|
|
55602
|
-
return value.endsWith("s") && value.length > 3 ? value.slice(0, -1) : value;
|
|
55634
|
+
return singularizeToken(value, ["changes", "status", "results"]);
|
|
55603
55635
|
}
|
|
55604
55636
|
function normalizeSubjectKey3(value) {
|
|
55605
55637
|
return slug2(value).split("_").map(singularize2).join(".");
|
|
@@ -55671,7 +55703,9 @@ function inferEvent(text) {
|
|
|
55671
55703
|
return eventName ?? "domain_event";
|
|
55672
55704
|
}
|
|
55673
55705
|
var DEFAULT_MIN_SCORE = 0.35;
|
|
55674
|
-
var init_predicate_utils = () => {
|
|
55706
|
+
var init_predicate_utils = __esm(() => {
|
|
55707
|
+
init_shared();
|
|
55708
|
+
});
|
|
55675
55709
|
|
|
55676
55710
|
// ../cli/dist/operations/modeling/predicate-ranker.js
|
|
55677
55711
|
function tokens3(value) {
|
|
@@ -56016,7 +56050,10 @@ var init_predicate_applicability = __esm(() => {
|
|
|
56016
56050
|
permission_rule: {
|
|
56017
56051
|
allOf: [
|
|
56018
56052
|
[/only|may|can|allowed|denied|forbidden|must\s+not|cannot/i],
|
|
56019
|
-
[
|
|
56053
|
+
[
|
|
56054
|
+
/delete|export|access|read|write|update|remove|manage|permission/i,
|
|
56055
|
+
/\b(?:may|can|cannot|can't|must\s+(?:not|never)|never|(?:is|are)\s+(?:not\s+)?(?:allowed|permitted|forbidden)\s+to)\s+(?:only\s+)?(?:publish|unpublish|approve|assign|view|see|edit|modify|create|submit|share|invite|upload|download|comment|post|complete|archive|restore|grant|revoke|purchase|cancel|execute|invoke|configure|moderate|ban|join|book|reserve|transfer|close|reopen|merge)\b/i
|
|
56056
|
+
]
|
|
56020
56057
|
]
|
|
56021
56058
|
},
|
|
56022
56059
|
resource_constraint: {
|
|
@@ -74965,6 +75002,17 @@ var init_cli_operation_metadata = __esm(() => {
|
|
|
74965
75002
|
// ../cli/dist/cli-validate.js
|
|
74966
75003
|
var init_cli_validate = () => {};
|
|
74967
75004
|
|
|
75005
|
+
// ../cli/dist/operations/planning/migration-refusal.js
|
|
75006
|
+
var MigrationActionRefusedError, MIGRATION_PLAN_REFUSED = "MIGRATION_PLAN_REFUSED";
|
|
75007
|
+
var init_migration_refusal = __esm(() => {
|
|
75008
|
+
MigrationActionRefusedError = class MigrationActionRefusedError extends Error {
|
|
75009
|
+
constructor(message) {
|
|
75010
|
+
super(message);
|
|
75011
|
+
this.name = "MigrationActionRefusedError";
|
|
75012
|
+
}
|
|
75013
|
+
};
|
|
75014
|
+
});
|
|
75015
|
+
|
|
74968
75016
|
// ../cli/dist/public/operations/result-envelope.js
|
|
74969
75017
|
function record4(value) {
|
|
74970
75018
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -75056,23 +75104,33 @@ function extraFailedEffects(declared, data) {
|
|
|
75056
75104
|
function resultVersion(spec) {
|
|
75057
75105
|
return spec.resultVersion ?? `kibi.${spec.name}.v1`;
|
|
75058
75106
|
}
|
|
75107
|
+
function refusalDetail(row) {
|
|
75108
|
+
const results = Array.isArray(row.actionResults) ? row.actionResults : [];
|
|
75109
|
+
const failure = results.find((entry) => record4(entry) && entry.outcome === "failed");
|
|
75110
|
+
return record4(failure) && typeof failure.detail === "string" ? failure.detail : "";
|
|
75111
|
+
}
|
|
75059
75112
|
function toKibiResult(spec, data, options2 = {}) {
|
|
75060
75113
|
const row = record4(data) ? data : undefined;
|
|
75114
|
+
const migrationRefused = row?.version === "kibi.migration-apply-result.v1" && row.outcome === "refused";
|
|
75061
75115
|
let status = options2.status;
|
|
75062
75116
|
if (!status) {
|
|
75063
75117
|
status = "success";
|
|
75064
75118
|
if (row?.status === "committed_with_repairs")
|
|
75065
75119
|
status = "committed_with_repairs";
|
|
75066
|
-
if (row?.status === "rejected")
|
|
75120
|
+
if (row?.status === "rejected" || migrationRefused)
|
|
75067
75121
|
status = "error";
|
|
75068
75122
|
}
|
|
75069
75123
|
const terminalError = row?.status === "rejected" ? {
|
|
75070
75124
|
code: "BOOTSTRAP_PLAN_REJECTED",
|
|
75071
75125
|
message: "Bootstrap stopped at a deterministic failure. Inspect actionResults for committed actions and re-plan from the current state.",
|
|
75072
75126
|
retryable: false
|
|
75127
|
+
} : migrationRefused ? {
|
|
75128
|
+
code: MIGRATION_PLAN_REFUSED,
|
|
75129
|
+
message: `Migration plan refused; nothing was changed. ${refusalDetail(row)}`.trim(),
|
|
75130
|
+
retryable: false
|
|
75073
75131
|
} : undefined;
|
|
75074
75132
|
const resultError = options2.error ?? terminalError;
|
|
75075
|
-
const outcome = effectOutcome(status, options2);
|
|
75133
|
+
const outcome = effectOutcome(status, migrationRefused && options2.attempted === undefined ? { ...options2, attempted: false } : options2);
|
|
75076
75134
|
return {
|
|
75077
75135
|
kibiProtocol: KIBI_PROTOCOL_VERSION,
|
|
75078
75136
|
operation: spec.name,
|
|
@@ -75121,6 +75179,9 @@ function appendPayloadCountField(fields, countKey, noun, payload) {
|
|
|
75121
75179
|
fields.result_summary = count === null ? `${noun} count unavailable` : `${count} ${noun}`;
|
|
75122
75180
|
}
|
|
75123
75181
|
var KIBI_PROTOCOL_VERSION = 1;
|
|
75182
|
+
var init_result_envelope = __esm(() => {
|
|
75183
|
+
init_migration_refusal();
|
|
75184
|
+
});
|
|
75124
75185
|
|
|
75125
75186
|
// ../cli/dist/cli-protocol.js
|
|
75126
75187
|
var import__2020, outputValidator;
|
|
@@ -75130,6 +75191,7 @@ var init_cli_protocol = __esm(() => {
|
|
|
75130
75191
|
init_cli_operation_metadata();
|
|
75131
75192
|
init_cli_validate();
|
|
75132
75193
|
init_engine_limits();
|
|
75194
|
+
init_result_envelope();
|
|
75133
75195
|
init_detached_snapshot();
|
|
75134
75196
|
import__2020 = __toESM(require__2020(), 1);
|
|
75135
75197
|
outputValidator = new import__2020.default({ strict: false, allErrors: true });
|
|
@@ -75138,6 +75200,7 @@ var init_cli_protocol = __esm(() => {
|
|
|
75138
75200
|
// ../cli/dist/public/diagnostic-usage.js
|
|
75139
75201
|
var RECEIPT_GAP_CODES;
|
|
75140
75202
|
var init_diagnostic_usage = __esm(() => {
|
|
75203
|
+
init_result_envelope();
|
|
75141
75204
|
RECEIPT_GAP_CODES = new Set([
|
|
75142
75205
|
"missing_proof_receipt",
|
|
75143
75206
|
"stale_proof_receipt",
|
|
@@ -76010,32 +76073,32 @@ function applyProofIntegrationAction(action, root) {
|
|
|
76010
76073
|
const evidence = action.evidence;
|
|
76011
76074
|
const integration = evidence.integration;
|
|
76012
76075
|
if (evidence.path !== PROOF_INTEGRATIONS_PATH || evidence.mode !== "create" && evidence.mode !== "update" || !isRecord22(integration) || typeof integration.id !== "string")
|
|
76013
|
-
throw new
|
|
76076
|
+
throw new MigrationActionRefusedError(`Proof integration action '${action.id}' is malformed; rerun kibi proof inspect for a new plan.`);
|
|
76014
76077
|
const planned = isRecord22(evidence.sourceHashes) ? evidence.sourceHashes : {};
|
|
76015
76078
|
const live = sourceHashes(root);
|
|
76016
76079
|
const changed = [
|
|
76017
76080
|
...new Set([...Object.keys(planned), ...Object.keys(live)])
|
|
76018
76081
|
].filter((file) => planned[file] !== live[file]);
|
|
76019
76082
|
if (changed.length > 0)
|
|
76020
|
-
throw new
|
|
76083
|
+
throw new MigrationActionRefusedError(`Proof integration plan refused: ${changed.join(", ")} changed since planning; rerun kibi proof inspect and review the new plan.`);
|
|
76021
76084
|
const filePath = integrationsPath(root);
|
|
76022
76085
|
let integrations;
|
|
76023
76086
|
if (evidence.mode === "create") {
|
|
76024
76087
|
if (existsSync42(filePath))
|
|
76025
|
-
throw new
|
|
76088
|
+
throw new MigrationActionRefusedError(`Proof integration plan refused: ${PROOF_INTEGRATIONS_PATH} already exists and this plan only creates it. Run kibi proof inspect --update <integration id> for a plan that adds or replaces one named integration.`);
|
|
76026
76089
|
integrations = [integration];
|
|
76027
76090
|
} else {
|
|
76028
76091
|
if (fileHash3(filePath) !== evidence.previousFileHash)
|
|
76029
|
-
throw new
|
|
76092
|
+
throw new MigrationActionRefusedError(`Proof integration plan refused: ${PROOF_INTEGRATIONS_PATH} changed since planning; rerun kibi proof inspect --update ${integration.id}.`);
|
|
76030
76093
|
const current = readIntegrationsFile(root);
|
|
76031
76094
|
if (current === null)
|
|
76032
|
-
throw new
|
|
76095
|
+
throw new MigrationActionRefusedError(`Proof integration plan refused: ${PROOF_INTEGRATIONS_PATH} is not a valid ${PROOF_INTEGRATION_VERSION} file.`);
|
|
76033
76096
|
integrations = current.integrations.some((entry) => entry.id === integration.id) ? current.integrations.map((entry) => entry.id === integration.id ? integration : entry) : [...current.integrations, integration];
|
|
76034
76097
|
}
|
|
76035
76098
|
const file = { version: PROOF_INTEGRATION_VERSION, integrations };
|
|
76036
76099
|
const errors = proofIntegrationErrors(file);
|
|
76037
76100
|
if (errors.length > 0)
|
|
76038
|
-
throw new
|
|
76101
|
+
throw new MigrationActionRefusedError(`Proof integration plan refused: the result would be invalid (${errors.join("; ")}).`);
|
|
76039
76102
|
mkdirSync17(path80.dirname(filePath), { recursive: true });
|
|
76040
76103
|
const temporary = `${filePath}.${process.pid}.tmp`;
|
|
76041
76104
|
writeFileSync20(temporary, `${JSON.stringify(file, null, 2)}
|
|
@@ -76044,6 +76107,7 @@ function applyProofIntegrationAction(action, root) {
|
|
|
76044
76107
|
}
|
|
76045
76108
|
var PROOF_INTEGRATION_CONFIGURE = "proof_integration_configure", PROPOSAL_SOURCES;
|
|
76046
76109
|
var init_integration_plan = __esm(() => {
|
|
76110
|
+
init_migration_refusal();
|
|
76047
76111
|
init_migration_plan();
|
|
76048
76112
|
init_proof_protocol();
|
|
76049
76113
|
init_integrations();
|
|
@@ -78531,6 +78595,8 @@ async function applyMigrationPlan(args, context, onCommitted = () => {
|
|
|
78531
78595
|
}
|
|
78532
78596
|
const results = [];
|
|
78533
78597
|
let failed = false;
|
|
78598
|
+
let refusals = 0;
|
|
78599
|
+
let failures = 0;
|
|
78534
78600
|
for (const action of actions) {
|
|
78535
78601
|
if (failed) {
|
|
78536
78602
|
results.push({
|
|
@@ -78550,6 +78616,9 @@ async function applyMigrationPlan(args, context, onCommitted = () => {
|
|
|
78550
78616
|
});
|
|
78551
78617
|
} catch (error) {
|
|
78552
78618
|
failed = true;
|
|
78619
|
+
failures += 1;
|
|
78620
|
+
if (error instanceof MigrationActionRefusedError)
|
|
78621
|
+
refusals += 1;
|
|
78553
78622
|
results.push({
|
|
78554
78623
|
actionId: action.id,
|
|
78555
78624
|
outcome: "failed",
|
|
@@ -78596,7 +78665,7 @@ async function applyMigrationPlan(args, context, onCommitted = () => {
|
|
|
78596
78665
|
});
|
|
78597
78666
|
}
|
|
78598
78667
|
}
|
|
78599
|
-
const outcome = failed ? results.some((result) => result.outcome === "applied") ? "partially_applied" : "reconciliation_required" : "applied";
|
|
78668
|
+
const outcome = failed ? results.some((result) => result.outcome === "applied") ? "partially_applied" : failures > 0 && refusals === failures ? "refused" : "reconciliation_required" : "applied";
|
|
78600
78669
|
const kbState = finalStatus.branchAttachment?.migrationRequired ? "legacy_compat" : finalStatus.syncState === "stale" ? "stale" : finalStatus.dirty ? "dirty" : finalStatus.syncState === "fresh" ? "clean_fresh" : "not_evaluated";
|
|
78601
78670
|
const snapshotState = finalStatus.proofSnapshotAvailable === false ? "unavailable" : finalStatus.proofSnapshotDirty === true ? "dirty" : finalStatus.proofSnapshotDirty === false ? "fresh" : "not_evaluated";
|
|
78602
78671
|
const proven = coverageSummary?.proofProven;
|
|
@@ -78617,7 +78686,7 @@ async function applyMigrationPlan(args, context, onCommitted = () => {
|
|
|
78617
78686
|
],
|
|
78618
78687
|
...remainingPlan !== undefined ? { remainingPlan } : {},
|
|
78619
78688
|
closeout: {
|
|
78620
|
-
taskOutcome: outcome === "applied" ? "complete" : outcome === "reconciliation_required" ? "blocked" : "interim",
|
|
78689
|
+
taskOutcome: outcome === "applied" ? "complete" : outcome === "reconciliation_required" || outcome === "refused" ? "blocked" : "interim",
|
|
78621
78690
|
kbState,
|
|
78622
78691
|
snapshotState,
|
|
78623
78692
|
proofState,
|
|
@@ -78628,7 +78697,7 @@ async function applyMigrationPlan(args, context, onCommitted = () => {
|
|
|
78628
78697
|
content: [
|
|
78629
78698
|
{
|
|
78630
78699
|
type: "text",
|
|
78631
|
-
text:
|
|
78700
|
+
text: outcome === "applied" ? `Applied migration plan ${args.plan.planHash.slice(0, 12)}.` : outcome === "refused" ? `Refused migration plan ${args.plan.planHash.slice(0, 12)}; nothing was changed.` : `Stopped after migration plan ${args.plan.planHash.slice(0, 12)}.`
|
|
78632
78701
|
}
|
|
78633
78702
|
],
|
|
78634
78703
|
structuredContent: payload
|
|
@@ -78703,16 +78772,16 @@ async function applyMigrationAction(action, context) {
|
|
|
78703
78772
|
await applySchema6MigrationAction(action, context);
|
|
78704
78773
|
return;
|
|
78705
78774
|
}
|
|
78706
|
-
throw new
|
|
78775
|
+
throw new MigrationActionRefusedError(`Migration action '${action.code}' has no automatic executor.`);
|
|
78707
78776
|
}
|
|
78708
78777
|
}
|
|
78709
78778
|
async function applyPredicateSchemaAlignment(action, context) {
|
|
78710
78779
|
const invocation = action.invocation;
|
|
78711
78780
|
if (invocation.kind !== "operation" || invocation.name !== "kb_upsert")
|
|
78712
|
-
throw new
|
|
78781
|
+
throw new MigrationActionRefusedError("Predicate schema alignment requires its planned kb_upsert invocation.");
|
|
78713
78782
|
const input = asUpsert(invocation.input);
|
|
78714
78783
|
if (input.type !== "fact")
|
|
78715
|
-
throw new
|
|
78784
|
+
throw new MigrationActionRefusedError("Predicate schema alignment only rewrites fact entities.");
|
|
78716
78785
|
const prolog = context.prolog ?? await context.ensureProlog?.();
|
|
78717
78786
|
if (!prolog)
|
|
78718
78787
|
throw new Error("Predicate schema alignment requires a Prolog runtime.");
|
|
@@ -78724,7 +78793,7 @@ async function applyPredicateSchemaAlignment(action, context) {
|
|
|
78724
78793
|
const rewrites = Array.isArray(evidence.rewrites) ? evidence.rewrites : [];
|
|
78725
78794
|
const unchanged = current !== undefined && current.fact_kind === "predicate" && currentNamespace === evidence.namespace && rewrites.every((rewrite) => isRecord24(rewrite) && typeof rewrite.index === "number" && currentArgs[rewrite.index] === rewrite.from);
|
|
78726
78795
|
if (!unchanged)
|
|
78727
|
-
throw new
|
|
78796
|
+
throw new MigrationActionRefusedError(`Predicate fact ${input.id} changed since planning; rerun kibi check and approve the new plan.`);
|
|
78728
78797
|
await executeUpsert(input, operationContext);
|
|
78729
78798
|
}
|
|
78730
78799
|
var PLAN_APPLY_RESULT_VERSION = "kibi.plan-apply-result.v1", ENTITY_TYPES4;
|
|
@@ -78752,6 +78821,7 @@ var init_apply_plan = __esm(() => {
|
|
|
78752
78821
|
init_upsert();
|
|
78753
78822
|
init_workspace_mutation_lock();
|
|
78754
78823
|
init_compile_intent();
|
|
78824
|
+
init_migration_refusal();
|
|
78755
78825
|
ENTITY_TYPES4 = new Set([
|
|
78756
78826
|
"req",
|
|
78757
78827
|
"scenario",
|
|
@@ -80347,6 +80417,7 @@ init_branch_store_locator();
|
|
|
80347
80417
|
init_detached_snapshot();
|
|
80348
80418
|
|
|
80349
80419
|
// src/index.ts
|
|
80420
|
+
init_result_envelope();
|
|
80350
80421
|
init_engine();
|
|
80351
80422
|
|
|
80352
80423
|
// ../cli/dist/public/prolog/index.js
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-usage
|
|
3
3
|
name: Kibi Usage
|
|
4
4
|
description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
|
|
5
|
-
version: 2.
|
|
5
|
+
version: 2.13.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -148,7 +148,13 @@ error `BOOTSTRAP_PLAN_REJECTED` can follow earlier committed actions: inspect
|
|
|
148
148
|
`data.actionResults` and `data.applied`, then re-plan from the current state.
|
|
149
149
|
Its journal is terminal; never recover or replay it. `BOOTSTRAP_PLAN_INVALID`
|
|
150
150
|
fails preflight before bootstrap writes or a new journal; obtain a corrected
|
|
151
|
-
plan.
|
|
151
|
+
plan. A migration plan whose actions were refused before changing anything
|
|
152
|
+
returns `status: error`, `MIGRATION_PLAN_REFUSED` and `data.outcome:
|
|
153
|
+
refused`: nothing changed, so read the action `detail` and get a new plan.
|
|
154
|
+
`data.outcome: reconciliation_required` (status success) means an action
|
|
155
|
+
failed mid-way: inspect its effect before retrying. `kb_delete` of an
|
|
156
|
+
authored entity returns status success with `deleted: 0`; its `errors` say
|
|
157
|
+
why nothing was deleted. If the status is
|
|
152
158
|
`committed_with_repairs`, the mutation already committed: inspect failed effects,
|
|
153
159
|
execute each required repair action in order, and never retry the original
|
|
154
160
|
operation. Record effect failures, followed actions, and unsafe retries in
|
|
@@ -61,16 +61,16 @@ A schema can close an argument with `argument_constants` (allowed values keyed b
|
|
|
61
61
|
|
|
62
62
|
### Deny predicate
|
|
63
63
|
|
|
64
|
-
Claim: “Suspended users must not publish articles.” When `permission_rule` fits, preserve its positive schema name and encode prohibition as polarity:
|
|
64
|
+
Claim: “Suspended users must not publish articles.” When `permission_rule` fits, preserve its positive schema name and encode prohibition as polarity. `kb_model` (`mode: "predicates"`) plans this fact for the claim; the built-in schema's fourth argument, `decision`, repeats the polarity:
|
|
65
65
|
|
|
66
66
|
```yaml
|
|
67
67
|
id: FACT-SUSPENDED-PUBLISH-DENIED
|
|
68
68
|
status: active
|
|
69
69
|
fact_kind: predicate
|
|
70
70
|
predicate_name: permission_rule
|
|
71
|
-
predicate_args: [suspended_user, publish,
|
|
71
|
+
predicate_args: [suspended_user, publish, articles, deny]
|
|
72
72
|
polarity: deny
|
|
73
|
-
canonical_key: permission_rule(suspended_user,publish,
|
|
73
|
+
canonical_key: permission_rule(suspended_user,publish,articles,deny)
|
|
74
74
|
claim_key: <advisor-issued key for this exact clause>
|
|
75
75
|
claim_text: Suspended users must not publish articles.
|
|
76
76
|
relationship: { type: requires_predicate, from: REQ-SUSPENDED-PUBLISH-DENIED, to: FACT-SUSPENDED-PUBLISH-DENIED }
|
|
@@ -51,6 +51,15 @@ proof_bindings: # optional provenance metadata
|
|
|
51
51
|
|
|
52
52
|
Provenance lives in `proof_bindings`; the contract stays semantic.
|
|
53
53
|
|
|
54
|
+
- Every `required_proofs[].symbol_id` must name an existing `symbol` entity,
|
|
55
|
+
or `kb_check` reports `proof-contract-symbols`. Create the symbols first
|
|
56
|
+
(`kb_upsert`, narrow method-level granularity, never a `type-shape`
|
|
57
|
+
symbol): a production symbol `implements` the requirement and is
|
|
58
|
+
`covered_by` the test; an executable test symbol is `executable_for` it.
|
|
59
|
+
- `proof_bindings[].source_file`, when set, must equal the named symbol's
|
|
60
|
+
`sourceFile`: for a production symbol that is the production file, not the
|
|
61
|
+
spec file that exercises it. Omit it when unsure.
|
|
62
|
+
|
|
54
63
|
## Integration configuration
|
|
55
64
|
|
|
56
65
|
`.kb/proof/integrations.json` (`kibi.proof-integration.v1`) is tracked,
|
|
@@ -62,12 +71,21 @@ returns `integrationPlan`, a hash-bound `kibi.migration-plan.v2`, plus the
|
|
|
62
71
|
proposal to the human, then apply the plan with `kb_apply_plan` (or
|
|
63
72
|
`kibi apply-plan --input -`) passing `plan`, `approvedPlanHash` (the plan's
|
|
64
73
|
`planHash`) and `approvedActionIds`. Once the file exists, a create plan is
|
|
65
|
-
refused
|
|
66
|
-
|
|
74
|
+
refused (`status: error`, `MIGRATION_PLAN_REFUSED`, `data.outcome: refused`;
|
|
75
|
+
nothing is written); `kibi proof inspect --update <id> --json` plans adding or
|
|
76
|
+
replacing one named integration.
|
|
67
77
|
|
|
68
78
|
- `producer: command` — Kibi synthesizes the envelope from the process
|
|
69
79
|
outcome; obligations are bound with `aggregate_run` provenance and the
|
|
70
|
-
single process invocation counts as the known first attempt.
|
|
80
|
+
single process invocation counts as the known first attempt. The run is
|
|
81
|
+
judged as a whole: any failing test in it fails every obligation of every
|
|
82
|
+
test that names the integration, so a suite with unrelated failures proves
|
|
83
|
+
nothing. Narrow the command to the proof-bearing tests with
|
|
84
|
+
`kibi proof inspect --update <id> --command "<command>" --json` (without
|
|
85
|
+
`--command` the proposal is the `package.json` `test` script or the
|
|
86
|
+
detected runner again), or make the run attributable per test: have the
|
|
87
|
+
command write a `kibi.proof-test-report.v1` to the path in
|
|
88
|
+
`KIBI_PROOF_TEST_REPORT` so each test is judged by its own steps.
|
|
71
89
|
- `producer: playwright` (or custom) — the child emits `kibi.proof-run.v1`
|
|
72
90
|
itself (bundled reporter: `kibi-cli/playwright-reporter`).
|
|
73
91
|
- `producer: junit` / `tap` — Kibi converts the native report at `artifact`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-runtime",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.2",
|
|
4
4
|
"description": "Narrow first-party runtime contracts and adapters for Kibi operations.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"gray-matter": "^4.0.3",
|
|
21
|
-
"kibi-core": "^0.18.
|
|
21
|
+
"kibi-core": "^0.18.2",
|
|
22
22
|
"kibi-plugin-builtin": "^0.5.0",
|
|
23
23
|
"kibi-swipl": "^1.0.1"
|
|
24
24
|
},
|