kibi-runtime 2.13.0 → 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 +1 -1
- package/dist/index.js +672 -251
- package/dist/skills/kibi-bootstrap/SKILL.md +2 -1
- package/dist/skills/kibi-usage/SKILL.md +21 -7
- package/dist/skills/kibi-usage/resources/fact-lanes.md +3 -3
- package/dist/skills/kibi-usage/resources/proof.md +34 -4
- package/package.json +2 -2
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() {
|
|
@@ -12218,7 +12218,7 @@ var init_search_answer = __esm(() => {
|
|
|
12218
12218
|
});
|
|
12219
12219
|
|
|
12220
12220
|
// ../cli/dist/utils/branch-store.js
|
|
12221
|
-
import { existsSync as existsSync10, readFileSync as readFileSync9, statSync as statSync6 } from "node:fs";
|
|
12221
|
+
import { existsSync as existsSync10, readFileSync as readFileSync9, readdirSync as readdirSync4, statSync as statSync6 } from "node:fs";
|
|
12222
12222
|
import * as path15 from "node:path";
|
|
12223
12223
|
function inspectBranchStore(workspaceRoot, branch) {
|
|
12224
12224
|
const storePath = branchStorePath(workspaceRoot, branch);
|
|
@@ -12354,9 +12354,86 @@ function branchStoreReason(inspection) {
|
|
|
12354
12354
|
remediation: inspection.recoveryRequired ? { command_argv: ["kibi", "branch", "recover"], applyRequired: true } : { command_argv: ["kibi", "branch", "ensure"], applyRequired: false }
|
|
12355
12355
|
};
|
|
12356
12356
|
}
|
|
12357
|
+
function countFiles(directory, extension) {
|
|
12358
|
+
let count = 0;
|
|
12359
|
+
let entries;
|
|
12360
|
+
try {
|
|
12361
|
+
entries = readdirSync4(directory, { withFileTypes: true });
|
|
12362
|
+
} catch {
|
|
12363
|
+
return 0;
|
|
12364
|
+
}
|
|
12365
|
+
for (const entry of entries) {
|
|
12366
|
+
if (entry.isDirectory()) {
|
|
12367
|
+
count += countFiles(path15.join(directory, entry.name), extension);
|
|
12368
|
+
} else if (entry.isFile() && entry.name.endsWith(extension)) {
|
|
12369
|
+
count += 1;
|
|
12370
|
+
}
|
|
12371
|
+
}
|
|
12372
|
+
return count;
|
|
12373
|
+
}
|
|
12374
|
+
function countAuthoredKbSources(workspaceRoot) {
|
|
12375
|
+
const kbRoot = path15.join(workspaceRoot, KB_ROOT);
|
|
12376
|
+
return AUTHORED_SOURCE_DIRECTORIES.reduce((total, [directory, extension]) => total + countFiles(path15.join(kbRoot, directory), extension), 0);
|
|
12377
|
+
}
|
|
12378
|
+
function branchStoreCompilation(inspection) {
|
|
12379
|
+
if (inspection.state === "missing") {
|
|
12380
|
+
return { compiled: false, generation: null };
|
|
12381
|
+
}
|
|
12382
|
+
const currentPath = path15.join(inspection.path, "CURRENT");
|
|
12383
|
+
let current = "";
|
|
12384
|
+
try {
|
|
12385
|
+
current = existsSync10(currentPath) ? readFileSync9(currentPath, "utf8").trim() : "";
|
|
12386
|
+
} catch {
|
|
12387
|
+
current = "";
|
|
12388
|
+
}
|
|
12389
|
+
if (current === "") {
|
|
12390
|
+
return { compiled: inspection.state === "healthy", generation: null };
|
|
12391
|
+
}
|
|
12392
|
+
const sequence = Number(current.split(":").at(-1));
|
|
12393
|
+
return {
|
|
12394
|
+
compiled: Number.isFinite(sequence) && sequence > 0 || journalHoldsGraphData(inspection.path),
|
|
12395
|
+
generation: current
|
|
12396
|
+
};
|
|
12397
|
+
}
|
|
12398
|
+
function journalHoldsGraphData(storePath) {
|
|
12399
|
+
try {
|
|
12400
|
+
return readdirSync4(path15.join(storePath, "rdf")).some((entry) => entry !== "lock" && !entry.startsWith("."));
|
|
12401
|
+
} catch {
|
|
12402
|
+
return false;
|
|
12403
|
+
}
|
|
12404
|
+
}
|
|
12405
|
+
function uncompiledBranchStoreReason(workspaceRoot, inspection, branch) {
|
|
12406
|
+
if (inspection.state !== "healthy" && inspection.state !== "missing") {
|
|
12407
|
+
return null;
|
|
12408
|
+
}
|
|
12409
|
+
const compilation = branchStoreCompilation(inspection);
|
|
12410
|
+
if (compilation.compiled)
|
|
12411
|
+
return null;
|
|
12412
|
+
const authoredSources = countAuthoredKbSources(workspaceRoot);
|
|
12413
|
+
if (authoredSources === 0)
|
|
12414
|
+
return null;
|
|
12415
|
+
const storeState = inspection.state === "missing" ? "does not exist yet" : `is empty (${compilation.generation ?? "no generation"}: nothing compiled)`;
|
|
12416
|
+
return {
|
|
12417
|
+
code: BRANCH_STORE_NOT_COMPILED,
|
|
12418
|
+
path: inspection.path,
|
|
12419
|
+
entityIds: [],
|
|
12420
|
+
detail: `The KB store for branch ${branch} ${storeState}, while .kb/ holds ${authoredSources} authored source file(s). Kibi compiles one store per branch and never copies another branch's, so every query and check reads an empty KB until this branch is compiled.`,
|
|
12421
|
+
remediation: { command_argv: ["kibi", "sync"], applyRequired: false },
|
|
12422
|
+
blocking: true,
|
|
12423
|
+
authoredSources,
|
|
12424
|
+
...compilation.generation !== null ? { generation: compilation.generation } : {}
|
|
12425
|
+
};
|
|
12426
|
+
}
|
|
12427
|
+
var BRANCH_STORE_NOT_COMPILED = "branch_store_not_compiled", BRANCH_STORE_NOT_COMPILED_RULE = "branch-store-not-compiled", AUTHORED_SOURCE_DIRECTORIES;
|
|
12357
12428
|
var init_branch_store = __esm(() => {
|
|
12358
12429
|
init_store_lock();
|
|
12359
12430
|
init_branch_store_locator();
|
|
12431
|
+
init_kb_paths();
|
|
12432
|
+
AUTHORED_SOURCE_DIRECTORIES = [
|
|
12433
|
+
...ENTITY_LANES.map((lane) => [lane, ".md"]),
|
|
12434
|
+
["adrs", ".md"],
|
|
12435
|
+
["relationships", ".yaml"]
|
|
12436
|
+
];
|
|
12360
12437
|
});
|
|
12361
12438
|
|
|
12362
12439
|
// ../cli/dist/utils/config.js
|
|
@@ -13381,8 +13458,27 @@ function buildActionsFromStatus(input) {
|
|
|
13381
13458
|
autoApplicable: configStatus.status !== "newer"
|
|
13382
13459
|
}));
|
|
13383
13460
|
}
|
|
13461
|
+
const uncompiled = (input.staleReasons ?? []).find((reason) => reason.code === BRANCH_STORE_NOT_COMPILED);
|
|
13462
|
+
if (uncompiled !== undefined) {
|
|
13463
|
+
actions.push(migrationAction({
|
|
13464
|
+
id: "branch-store-compile",
|
|
13465
|
+
code: BRANCH_STORE_NOT_COMPILED,
|
|
13466
|
+
category: "storage",
|
|
13467
|
+
safety: "automatic",
|
|
13468
|
+
invocation: { kind: "cli", command_argv: ["kibi", "sync"] },
|
|
13469
|
+
affectedFiles: [
|
|
13470
|
+
typeof store?.path === "string" ? store.path : ".kb/branches"
|
|
13471
|
+
],
|
|
13472
|
+
evidence: { reason: uncompiled },
|
|
13473
|
+
dependsOn: actions.map((action) => action.id).filter((id) => id === "branch-store-ensure" || id === "schema-config-upgrade"),
|
|
13474
|
+
postconditions: [{ branchStore: "compiled" }],
|
|
13475
|
+
autoApplicable: true
|
|
13476
|
+
}));
|
|
13477
|
+
}
|
|
13384
13478
|
for (const reason of input.staleReasons ?? []) {
|
|
13385
13479
|
const code = typeof reason.code === "string" ? reason.code : "stale_source";
|
|
13480
|
+
if (code === BRANCH_STORE_NOT_COMPILED)
|
|
13481
|
+
continue;
|
|
13386
13482
|
const file = typeof reason.path === "string" ? reason.path : "";
|
|
13387
13483
|
actions.push(migrationAction({
|
|
13388
13484
|
id: `freshness-${code}-${file}`,
|
|
@@ -13448,6 +13544,7 @@ function buildActionsFromStatus(input) {
|
|
|
13448
13544
|
}
|
|
13449
13545
|
var MIGRATION_PLAN_VERSION = "kibi.migration-plan.v2", PREDICATE_SCHEMA_ALIGNMENT_CODE = "predicate_schema_alignment";
|
|
13450
13546
|
var init_migration_plan = __esm(() => {
|
|
13547
|
+
init_branch_store();
|
|
13451
13548
|
init_config();
|
|
13452
13549
|
init_kb_manifest();
|
|
13453
13550
|
init_schema6_check_actions();
|
|
@@ -13659,7 +13756,8 @@ async function executeStatus(_input, context) {
|
|
|
13659
13756
|
}
|
|
13660
13757
|
const snapshotEvidence = await readWorkspaceSnapshot(context);
|
|
13661
13758
|
const existingReasons = payload.staleReasons ?? [];
|
|
13662
|
-
const storeReason = branchStoreReason(store);
|
|
13759
|
+
const storeReason = uncompiledBranchStoreReason(context.workspaceRoot, store, attachment.kbBranch) ?? branchStoreReason(store);
|
|
13760
|
+
const storeUncompiled = storeReason?.code === BRANCH_STORE_NOT_COMPILED;
|
|
13663
13761
|
const lockReason = storeLockJournalReason(store.path);
|
|
13664
13762
|
const compilerReason = compilerFingerprintReason(store.path);
|
|
13665
13763
|
const engineReason = engineStatus ? {
|
|
@@ -13682,6 +13780,7 @@ async function executeStatus(_input, context) {
|
|
|
13682
13780
|
const enrichedPayload = {
|
|
13683
13781
|
...payload,
|
|
13684
13782
|
...compilerReason ? { syncState: "stale", dirty: true } : {},
|
|
13783
|
+
...storeUncompiled ? { syncState: "stale", dirty: true } : {},
|
|
13685
13784
|
branchAttachment: attachment,
|
|
13686
13785
|
branchStore: store,
|
|
13687
13786
|
...engineStatus ? { engineStatus } : {},
|
|
@@ -13786,7 +13885,7 @@ async function executeStatus(_input, context) {
|
|
|
13786
13885
|
content: [
|
|
13787
13886
|
{
|
|
13788
13887
|
type: "text",
|
|
13789
|
-
text: `Branch ${payload.branch} is ${
|
|
13888
|
+
text: `Branch ${payload.branch} is ${enrichedPayload.syncState} (snapshot ${payload.snapshotId}, dirty=${enrichedPayload.dirty}, proofSnapshot=${enrichedPayload.proofSnapshot})${storeUncompiled ? `. Blocking: ${String(storeReason?.detail)} Run kibi sync.` : ""}`
|
|
13790
13889
|
}
|
|
13791
13890
|
],
|
|
13792
13891
|
structuredContent: statusWithPlan
|
|
@@ -13988,10 +14087,21 @@ function sourceOf(payload) {
|
|
|
13988
14087
|
function normalizeKey(value) {
|
|
13989
14088
|
return value.trim().toLowerCase().replace(/['’]/g, "").replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
13990
14089
|
}
|
|
13991
|
-
function
|
|
13992
|
-
if (
|
|
14090
|
+
function singularizeToken(value, keep = []) {
|
|
14091
|
+
if (value.length <= 3 || keep.includes(value))
|
|
13993
14092
|
return value;
|
|
13994
|
-
|
|
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))
|
|
14100
|
+
return value;
|
|
14101
|
+
return value.slice(0, -1);
|
|
14102
|
+
}
|
|
14103
|
+
function singularize(value) {
|
|
14104
|
+
return singularizeToken(value, ["status", "results"]);
|
|
13995
14105
|
}
|
|
13996
14106
|
function normalizeSubjectKey(value) {
|
|
13997
14107
|
return normalizeKey(value).split("_").map(singularize).join(".");
|
|
@@ -14121,9 +14231,10 @@ function predicateSuggestion(payload, evidence, name, args, rationale, polarity
|
|
|
14121
14231
|
} : null
|
|
14122
14232
|
};
|
|
14123
14233
|
}
|
|
14124
|
-
var SEMANTIC_INVENTORY_VERSION = "kibi.semantic-inventory.v1";
|
|
14234
|
+
var SEMANTIC_INVENTORY_VERSION = "kibi.semantic-inventory.v1", ES_PLURAL_SUFFIXES;
|
|
14125
14235
|
var init_shared = __esm(() => {
|
|
14126
14236
|
init_clauses();
|
|
14237
|
+
ES_PLURAL_SUFFIXES = ["ches", "shes", "sses", "xes"];
|
|
14127
14238
|
});
|
|
14128
14239
|
|
|
14129
14240
|
// ../cli/dist/operations/semantic-advisor/ingestion-boundary.js
|
|
@@ -23280,6 +23391,12 @@ var init_rule_registry_generated = __esm(() => {
|
|
|
23280
23391
|
enforcementClass: "canonical",
|
|
23281
23392
|
category: "integrity"
|
|
23282
23393
|
},
|
|
23394
|
+
{
|
|
23395
|
+
name: "branch-store-not-compiled",
|
|
23396
|
+
description: "The current branch's KB store must be compiled from the authored .kb/ sources; a missing or empty store is reported once, naming kibi sync, instead of every store-backed rule reading an empty KB",
|
|
23397
|
+
enforcementClass: "canonical",
|
|
23398
|
+
category: "integrity"
|
|
23399
|
+
},
|
|
23283
23400
|
{
|
|
23284
23401
|
name: "source-path-dangling",
|
|
23285
23402
|
description: "An authored entity's source field must name an existing workspace path (a #anchor suffix is ignored), an existing entity id, or an http(s) URL; a missing source is allowed",
|
|
@@ -23614,7 +23731,9 @@ function buildStableRequirementIds(claim) {
|
|
|
23614
23731
|
function buildStrictWriteSet(input) {
|
|
23615
23732
|
const statement = normalizeStatement(input.statement);
|
|
23616
23733
|
const confidence = normalizeConfidence(input.claim.confidence);
|
|
23617
|
-
const
|
|
23734
|
+
const minted = buildStableRequirementIds(input.claim);
|
|
23735
|
+
const requirementId = input.requirementId?.trim();
|
|
23736
|
+
const ids = requirementId ? { ...minted, reqId: requirementId } : minted;
|
|
23618
23737
|
const textRef = normalizeTextRef(input.claim.provenance, input.claim.source);
|
|
23619
23738
|
const metadataTags = buildMetadataTags({
|
|
23620
23739
|
confidence,
|
|
@@ -23904,6 +24023,9 @@ function normalizeEntityDirectory(directory) {
|
|
|
23904
24023
|
function buildEntitySourcePath(directory, entityId) {
|
|
23905
24024
|
return `${directory}/${entityId}.md`;
|
|
23906
24025
|
}
|
|
24026
|
+
function factSourcePath(factId) {
|
|
24027
|
+
return buildEntitySourcePath(resolveEntitySourcePaths().facts, factId);
|
|
24028
|
+
}
|
|
23907
24029
|
var STRICT_CONFIDENCE_THRESHOLD = 0.7, SUBJECT_KEY_CONVENTION, ORDERING_OPERATORS;
|
|
23908
24030
|
var init_strict_modeling = __esm(() => {
|
|
23909
24031
|
init_kb_paths();
|
|
@@ -27187,7 +27309,11 @@ function reuseExistingSubject(writeSet, existingFactId) {
|
|
|
27187
27309
|
subjectFact: {
|
|
27188
27310
|
...writeSet.subjectFact,
|
|
27189
27311
|
id: existingFactId,
|
|
27190
|
-
properties: {
|
|
27312
|
+
properties: {
|
|
27313
|
+
...writeSet.subjectFact.properties,
|
|
27314
|
+
id: existingFactId,
|
|
27315
|
+
source: factSourcePath(existingFactId)
|
|
27316
|
+
}
|
|
27191
27317
|
},
|
|
27192
27318
|
relationships: writeSet.relationships.map((relationship) => relationship.type === "constrains" ? { ...relationship, to: existingFactId } : relationship)
|
|
27193
27319
|
}
|
|
@@ -27213,10 +27339,11 @@ function possibleDuplicateObservation(claimKey, statement, source, candidates) {
|
|
|
27213
27339
|
}))
|
|
27214
27340
|
};
|
|
27215
27341
|
}
|
|
27216
|
-
async function applyVocabularyAlignment(context, extracted, claimKey) {
|
|
27342
|
+
async function applyVocabularyAlignment(context, extracted, claimKey, requirementId) {
|
|
27217
27343
|
const initial = buildStrictWriteSet({
|
|
27218
27344
|
claim: extracted.claim,
|
|
27219
|
-
statement: extracted.statement
|
|
27345
|
+
statement: extracted.statement,
|
|
27346
|
+
...requirementId !== undefined ? { requirementId } : {}
|
|
27220
27347
|
});
|
|
27221
27348
|
const unchanged = {
|
|
27222
27349
|
writeSet: initial,
|
|
@@ -27244,7 +27371,8 @@ async function applyVocabularyAlignment(context, extracted, claimKey) {
|
|
|
27244
27371
|
if (followsVocabulary) {
|
|
27245
27372
|
const rebuilt = buildStrictWriteSet({
|
|
27246
27373
|
claim: { ...extracted.claim, subjectKey: subject.subjectKey },
|
|
27247
|
-
statement: extracted.statement
|
|
27374
|
+
statement: extracted.statement,
|
|
27375
|
+
...requirementId !== undefined ? { requirementId } : {}
|
|
27248
27376
|
});
|
|
27249
27377
|
({ writeSet, replacedSubjectId } = reuseExistingSubject(rebuilt, subject.existingFactId));
|
|
27250
27378
|
} else {
|
|
@@ -27534,7 +27662,7 @@ async function handleKbModelRequirement(_prolog, args, workspaceRoot, context) {
|
|
|
27534
27662
|
if (conditional?.kind === "unparsed")
|
|
27535
27663
|
return unresolvedConditionalResult(args, extracted, conditional.reason, workspaceRoot);
|
|
27536
27664
|
const claimKey = semanticClaimKey(extracted.statement);
|
|
27537
|
-
const aligned = await applyVocabularyAlignment(context, extracted, claimKey);
|
|
27665
|
+
const aligned = await applyVocabularyAlignment(context, extracted, claimKey, normalizeOptionalString(args.requirementId));
|
|
27538
27666
|
const writeSet = aligned.writeSet;
|
|
27539
27667
|
const logicClaims = Array.from(new Set([...args.existingLogicClaims ?? [], claimKey]));
|
|
27540
27668
|
const plan = aligned.adjustPlan(strictWriteSetToApplyPlan(writeSet));
|
|
@@ -43258,13 +43386,34 @@ function coverageForRequirement(result, manifestResults, entities) {
|
|
|
43258
43386
|
scenarioTests
|
|
43259
43387
|
};
|
|
43260
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
|
+
}
|
|
43261
43400
|
function createCoverageDepthQualityDiagnostics(manifestResults, proofByRequirement = new Map) {
|
|
43262
43401
|
const entities = entitiesById(manifestResults);
|
|
43263
|
-
|
|
43402
|
+
const superseded = supersededRequirementIds(manifestResults);
|
|
43403
|
+
return manifestResults.filter((result) => result.entity.type === "req" && isReviewableRequirement(result.entity, superseded)).flatMap((result) => {
|
|
43264
43404
|
const diagnostic = createDiagnostic(coverageForRequirement(result, manifestResults, entities), proofByRequirement.get(result.entity.id));
|
|
43265
43405
|
return diagnostic === undefined ? [] : [diagnostic];
|
|
43266
43406
|
}).toSorted((left, right) => (left.entityId ?? "").localeCompare(right.entityId ?? ""));
|
|
43267
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
|
+
});
|
|
43268
43417
|
|
|
43269
43418
|
// ../cli/dist/public/impact/requirement-quality.js
|
|
43270
43419
|
function isRequirement2(result) {
|
|
@@ -43937,6 +44086,7 @@ var init_full_kb_quality = __esm(() => {
|
|
|
43937
44086
|
init_proof_receipt();
|
|
43938
44087
|
init_relationship();
|
|
43939
44088
|
init_telemetry_acceptance();
|
|
44089
|
+
init_coverage_depth_quality();
|
|
43940
44090
|
init_requirement_quality();
|
|
43941
44091
|
init_symbol_quality();
|
|
43942
44092
|
RELATIONSHIP_TYPES = relationship_default.properties.type.enum;
|
|
@@ -44852,13 +45002,13 @@ var init_check_policy_rules = __esm(() => {
|
|
|
44852
45002
|
});
|
|
44853
45003
|
|
|
44854
45004
|
// ../cli/dist/operations/migration/kb-sources.js
|
|
44855
|
-
import { existsSync as existsSync21, mkdirSync as mkdirSync7, readFileSync as readFileSync24, readdirSync as
|
|
45005
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync7, readFileSync as readFileSync24, readdirSync as readdirSync6, renameSync as renameSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
44856
45006
|
import path45 from "node:path";
|
|
44857
45007
|
import { isDeepStrictEqual } from "node:util";
|
|
44858
45008
|
function walkMarkdown(directory, files) {
|
|
44859
45009
|
let entries;
|
|
44860
45010
|
try {
|
|
44861
|
-
entries =
|
|
45011
|
+
entries = readdirSync6(directory, { withFileTypes: true, encoding: "utf8" });
|
|
44862
45012
|
} catch {
|
|
44863
45013
|
return;
|
|
44864
45014
|
}
|
|
@@ -53447,7 +53597,7 @@ var require_out4 = __commonJS(function(exports2, module2) {
|
|
|
53447
53597
|
import { execFile } from "node:child_process";
|
|
53448
53598
|
import { createHash as createHash24 } from "node:crypto";
|
|
53449
53599
|
import * as fs7 from "node:fs";
|
|
53450
|
-
import { existsSync as existsSync23, readFileSync as readFileSync27, readdirSync as
|
|
53600
|
+
import { existsSync as existsSync23, readFileSync as readFileSync27, readdirSync as readdirSync7, unlinkSync as unlinkSync4 } from "node:fs";
|
|
53451
53601
|
import * as path49 from "node:path";
|
|
53452
53602
|
import { promisify } from "node:util";
|
|
53453
53603
|
async function gitTrackedPaths(cwd) {
|
|
@@ -53461,7 +53611,7 @@ function pendingSourcePaths(cwd, recoverMissing) {
|
|
|
53461
53611
|
}
|
|
53462
53612
|
const paths = new Map;
|
|
53463
53613
|
const recoveredReceipts = [];
|
|
53464
|
-
for (const name of
|
|
53614
|
+
for (const name of readdirSync7(root)) {
|
|
53465
53615
|
if (!name.endsWith(".json"))
|
|
53466
53616
|
continue;
|
|
53467
53617
|
const receiptPath = path49.join(root, name);
|
|
@@ -53614,7 +53764,7 @@ async function discoverSourceFiles(cwd, options2 = {}) {
|
|
|
53614
53764
|
}
|
|
53615
53765
|
const pendingRoot = path49.join(cwd, ".kb", "recovery", "pending-sources");
|
|
53616
53766
|
if (options2.consumeTrackedPendingReceipts !== false && existsSync23(pendingRoot)) {
|
|
53617
|
-
for (const name of
|
|
53767
|
+
for (const name of readdirSync7(pendingRoot)) {
|
|
53618
53768
|
if (!name.endsWith(".json"))
|
|
53619
53769
|
continue;
|
|
53620
53770
|
try {
|
|
@@ -54176,7 +54326,8 @@ __export(exports_check_executor, {
|
|
|
54176
54326
|
buildSummary: () => buildSummary,
|
|
54177
54327
|
executeCheck: () => executeCheck,
|
|
54178
54328
|
getEffectiveRules: () => getEffectiveRules,
|
|
54179
|
-
resolveCheckRules: () => resolveCheckRules
|
|
54329
|
+
resolveCheckRules: () => resolveCheckRules,
|
|
54330
|
+
uncompiledBranchStoreViolation: () => uncompiledBranchStoreViolation
|
|
54180
54331
|
});
|
|
54181
54332
|
function requireProlog2(context) {
|
|
54182
54333
|
if (context.prolog === undefined) {
|
|
@@ -54212,6 +54363,33 @@ async function readStatusMigrationPlan(context) {
|
|
|
54212
54363
|
throw error;
|
|
54213
54364
|
}
|
|
54214
54365
|
}
|
|
54366
|
+
function uncompiledBranchStoreViolation(context, workspaceRoot) {
|
|
54367
|
+
let attachment;
|
|
54368
|
+
try {
|
|
54369
|
+
attachment = context.branchAttachment ?? resolveBranchAttachment(workspaceRoot);
|
|
54370
|
+
} catch {
|
|
54371
|
+
return null;
|
|
54372
|
+
}
|
|
54373
|
+
if ("error" in attachment)
|
|
54374
|
+
return null;
|
|
54375
|
+
const store = inspectBranchStore(workspaceRoot, attachment.kbBranch);
|
|
54376
|
+
const reason = uncompiledBranchStoreReason(workspaceRoot, store, attachment.kbBranch);
|
|
54377
|
+
if (reason === null)
|
|
54378
|
+
return null;
|
|
54379
|
+
return {
|
|
54380
|
+
rule: BRANCH_STORE_NOT_COMPILED_RULE,
|
|
54381
|
+
entityId: attachment.kbBranch,
|
|
54382
|
+
description: String(reason.detail),
|
|
54383
|
+
suggestion: "Run kibi sync to compile this branch's store from the authored .kb/ sources (or apply the branch-store-compile action of the returned migrationPlan with kb_apply_plan), then rerun kb_check. Run kibi init once to install the git hooks that compile a new branch on checkout.",
|
|
54384
|
+
source: store.path,
|
|
54385
|
+
evidence: {
|
|
54386
|
+
store: { state: store.state, path: store.path },
|
|
54387
|
+
authoredSources: reason.authoredSources,
|
|
54388
|
+
...reason.generation !== undefined ? { generation: reason.generation } : {},
|
|
54389
|
+
remediation: reason.remediation
|
|
54390
|
+
}
|
|
54391
|
+
};
|
|
54392
|
+
}
|
|
54215
54393
|
async function executeCheck(args, context, options2 = {}) {
|
|
54216
54394
|
try {
|
|
54217
54395
|
const workspaceRoot = args.workspaceRoot ?? context.workspaceRoot;
|
|
@@ -54227,6 +54405,39 @@ async function executeCheck(args, context, options2 = {}) {
|
|
|
54227
54405
|
...stagedEntityIdStyleDiagnostics(workspaceRoot, args)
|
|
54228
54406
|
];
|
|
54229
54407
|
const maxDiagnosticsOption = args.maxDiagnostics !== undefined ? { maxDiagnostics: args.maxDiagnostics } : {};
|
|
54408
|
+
const uncompiled = context.branchAttachment !== undefined || options2.branchStoreAttached === true ? uncompiledBranchStoreViolation(context, workspaceRoot) : null;
|
|
54409
|
+
if (uncompiled !== null) {
|
|
54410
|
+
const violations = [uncompiled];
|
|
54411
|
+
const statusPlan = await readStatusMigrationPlan(context);
|
|
54412
|
+
const migrationPlan = await migrationPlanForCheck(context, violations, [], statusPlan);
|
|
54413
|
+
return {
|
|
54414
|
+
content: [
|
|
54415
|
+
{
|
|
54416
|
+
type: "text",
|
|
54417
|
+
text: buildSummary({
|
|
54418
|
+
violations,
|
|
54419
|
+
impactResult,
|
|
54420
|
+
qualityDiagnostics: []
|
|
54421
|
+
})
|
|
54422
|
+
}
|
|
54423
|
+
],
|
|
54424
|
+
structuredContent: buildStructuredContent({
|
|
54425
|
+
violations,
|
|
54426
|
+
diagnostics: [
|
|
54427
|
+
{
|
|
54428
|
+
category: "SYNC_ERROR",
|
|
54429
|
+
severity: "error",
|
|
54430
|
+
message: uncompiled.description,
|
|
54431
|
+
...uncompiled.source !== undefined ? { file: uncompiled.source } : {},
|
|
54432
|
+
...uncompiled.suggestion !== undefined ? { suggestion: uncompiled.suggestion } : {}
|
|
54433
|
+
}
|
|
54434
|
+
],
|
|
54435
|
+
qualityDiagnostics: [],
|
|
54436
|
+
impactResult,
|
|
54437
|
+
migrationPlan
|
|
54438
|
+
})
|
|
54439
|
+
};
|
|
54440
|
+
}
|
|
54230
54441
|
if (rulesAllowlist.size === 0) {
|
|
54231
54442
|
const qualityDiagnostics = hasExplicitRules && options2.collectFullQualityDiagnosticsForExplicitRules !== true ? [] : impactResult ? impactQualityDiagnostics : await collectFullKbQualityDiagnostics({
|
|
54232
54443
|
prolog,
|
|
@@ -54327,6 +54538,8 @@ async function executeCheck(args, context, options2 = {}) {
|
|
|
54327
54538
|
}
|
|
54328
54539
|
var init_check_executor = __esm(() => {
|
|
54329
54540
|
init_aggregated_checks();
|
|
54541
|
+
init_branch_resolver();
|
|
54542
|
+
init_branch_store();
|
|
54330
54543
|
init_impact_diagnostics();
|
|
54331
54544
|
init_check_helpers();
|
|
54332
54545
|
init_check_policy_rules();
|
|
@@ -54340,7 +54553,7 @@ var init_check_executor = __esm(() => {
|
|
|
54340
54553
|
});
|
|
54341
54554
|
|
|
54342
54555
|
// ../cli/dist/public/operations/specs/check-rules.generated.js
|
|
54343
|
-
var SELECTABLE_RULE_NAMES, SELECTABLE_RULES_ALLOWED = "must-priority-coverage, symbol-coverage, symbol-traceability, no-dangling-refs, source-relationship-parity, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, policy-ownership, policy-markers";
|
|
54556
|
+
var SELECTABLE_RULE_NAMES, SELECTABLE_RULES_ALLOWED = "must-priority-coverage, symbol-coverage, symbol-traceability, no-dangling-refs, source-relationship-parity, branch-store-not-compiled, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, policy-ownership, policy-markers";
|
|
54344
54557
|
var init_check_rules_generated = __esm(() => {
|
|
54345
54558
|
SELECTABLE_RULE_NAMES = [
|
|
54346
54559
|
"must-priority-coverage",
|
|
@@ -54348,6 +54561,7 @@ var init_check_rules_generated = __esm(() => {
|
|
|
54348
54561
|
"symbol-traceability",
|
|
54349
54562
|
"no-dangling-refs",
|
|
54350
54563
|
"source-relationship-parity",
|
|
54564
|
+
"branch-store-not-compiled",
|
|
54351
54565
|
"source-path-dangling",
|
|
54352
54566
|
"no-cycles",
|
|
54353
54567
|
"required-fields",
|
|
@@ -55417,9 +55631,7 @@ function normalizePredicateToken(value) {
|
|
|
55417
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, "");
|
|
55418
55632
|
}
|
|
55419
55633
|
function singularize2(value) {
|
|
55420
|
-
|
|
55421
|
-
return value;
|
|
55422
|
-
return value.endsWith("s") && value.length > 3 ? value.slice(0, -1) : value;
|
|
55634
|
+
return singularizeToken(value, ["changes", "status", "results"]);
|
|
55423
55635
|
}
|
|
55424
55636
|
function normalizeSubjectKey3(value) {
|
|
55425
55637
|
return slug2(value).split("_").map(singularize2).join(".");
|
|
@@ -55491,7 +55703,9 @@ function inferEvent(text) {
|
|
|
55491
55703
|
return eventName ?? "domain_event";
|
|
55492
55704
|
}
|
|
55493
55705
|
var DEFAULT_MIN_SCORE = 0.35;
|
|
55494
|
-
var init_predicate_utils = () => {
|
|
55706
|
+
var init_predicate_utils = __esm(() => {
|
|
55707
|
+
init_shared();
|
|
55708
|
+
});
|
|
55495
55709
|
|
|
55496
55710
|
// ../cli/dist/operations/modeling/predicate-ranker.js
|
|
55497
55711
|
function tokens3(value) {
|
|
@@ -55836,7 +56050,10 @@ var init_predicate_applicability = __esm(() => {
|
|
|
55836
56050
|
permission_rule: {
|
|
55837
56051
|
allOf: [
|
|
55838
56052
|
[/only|may|can|allowed|denied|forbidden|must\s+not|cannot/i],
|
|
55839
|
-
[
|
|
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
|
+
]
|
|
55840
56057
|
]
|
|
55841
56058
|
},
|
|
55842
56059
|
resource_constraint: {
|
|
@@ -57028,8 +57245,9 @@ function buildSuggestion(schema, text, subject, score, argumentBindings = {}, po
|
|
|
57028
57245
|
constrainedSubjects
|
|
57029
57246
|
})
|
|
57030
57247
|
]));
|
|
57031
|
-
const
|
|
57032
|
-
const
|
|
57248
|
+
const plannedSubjects = constrainedSubjects.length > 0 ? constrainedSubjects : explicitSubject ? [subject] : [];
|
|
57249
|
+
const subjectKey = plannedSubjects.length === 0 ? null : subjectArgument >= 0 ? predicateArgs[subjectArgument] ?? null : reviewedSubject ?? null;
|
|
57250
|
+
const subjectPairing = plannedSubjects.length === 0 ? "not_required" : subjectKey !== null && plannedSubjects.includes(subjectKey) ? "paired" : "unpaired";
|
|
57033
57251
|
const bindingProvenance = aggregateBindingProvenance(Object.values(bindingProvenanceByArgument));
|
|
57034
57252
|
const unboundArguments = schema.argument_names.filter((name) => undeclaredArguments.has(name) || !bindingCanBeApplied(bindingProvenanceByArgument[name] ?? "placeholder"));
|
|
57035
57253
|
if (subjectPairing === "unpaired") {
|
|
@@ -57831,7 +58049,7 @@ var init_modeling = __esm(() => {
|
|
|
57831
58049
|
},
|
|
57832
58050
|
requirementId: {
|
|
57833
58051
|
type: "string",
|
|
57834
|
-
description: "Optional
|
|
58052
|
+
description: "Optional requirement ID. The strict write set updates this requirement instead of minting a REQ-AUTO id, and a typed logic rule attaches its requires_rule relationship to it."
|
|
57835
58053
|
},
|
|
57836
58054
|
claimKey: {
|
|
57837
58055
|
type: "string",
|
|
@@ -61714,7 +61932,7 @@ var init_validation3 = __esm(() => {
|
|
|
61714
61932
|
});
|
|
61715
61933
|
|
|
61716
61934
|
// ../cli/dist/public/skill-system/loader.js
|
|
61717
|
-
import { existsSync as existsSync25, readFileSync as readFileSync29, readdirSync as
|
|
61935
|
+
import { existsSync as existsSync25, readFileSync as readFileSync29, readdirSync as readdirSync8, realpathSync as realpathSync8 } from "node:fs";
|
|
61718
61936
|
import { dirname as dirname11, join as join20, resolve as resolve16 } from "node:path";
|
|
61719
61937
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
61720
61938
|
function listBundledSkills() {
|
|
@@ -61735,7 +61953,7 @@ function readBundledSkillResource(id, resourcePath) {
|
|
|
61735
61953
|
function listFrom(dir) {
|
|
61736
61954
|
if (!existsSync25(dir))
|
|
61737
61955
|
return [];
|
|
61738
|
-
return
|
|
61956
|
+
return readdirSync8(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join20(dir, entry.name)).filter((root) => existsSync25(join20(root, SKILL_FILE_NAME))).map((root) => parseSkillBundle(root).manifest).sort((a, b) => a.id.localeCompare(b.id));
|
|
61739
61957
|
}
|
|
61740
61958
|
function findRoot(dir, id) {
|
|
61741
61959
|
return listRoots(dir).find((root) => parseSkillBundle(root).manifest.id === id);
|
|
@@ -61743,7 +61961,7 @@ function findRoot(dir, id) {
|
|
|
61743
61961
|
function listRoots(dir) {
|
|
61744
61962
|
if (!existsSync25(dir))
|
|
61745
61963
|
return [];
|
|
61746
|
-
return
|
|
61964
|
+
return readdirSync8(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join20(dir, entry.name)).filter((root) => existsSync25(join20(root, SKILL_FILE_NAME)));
|
|
61747
61965
|
}
|
|
61748
61966
|
function readBundle(bundle, id, resourcePath) {
|
|
61749
61967
|
const resource = normalizeResourcePath(resourcePath);
|
|
@@ -61898,6 +62116,28 @@ function requiredFields(spec) {
|
|
|
61898
62116
|
const required = spec.businessInputSchema.required;
|
|
61899
62117
|
return Array.isArray(required) ? required : [];
|
|
61900
62118
|
}
|
|
62119
|
+
function foreignParameterWarnings(selector, choice, routes, rest) {
|
|
62120
|
+
const route = routes[choice];
|
|
62121
|
+
if (route === undefined)
|
|
62122
|
+
return [];
|
|
62123
|
+
const own = new Set(Object.keys(properties2(route)));
|
|
62124
|
+
const equivalents = route.name === undefined ? {} : EQUIVALENT_PARAMETERS[route.name] ?? {};
|
|
62125
|
+
const warnings = [];
|
|
62126
|
+
for (const parameter of Object.keys(rest)) {
|
|
62127
|
+
if (own.has(parameter) || rest[parameter] === undefined)
|
|
62128
|
+
continue;
|
|
62129
|
+
const owners = Object.entries(routes).filter(([other, otherRoute]) => other !== choice && (parameter in properties2(otherRoute))).map(([other]) => `${selector}: ${other}`);
|
|
62130
|
+
if (owners.length === 0)
|
|
62131
|
+
continue;
|
|
62132
|
+
const equivalent = equivalents[parameter];
|
|
62133
|
+
warnings.push({
|
|
62134
|
+
parameter,
|
|
62135
|
+
message: `${parameter} is a ${owners.join(" / ")} argument; ${selector}: ${choice} ignored it.`,
|
|
62136
|
+
nextAction: equivalent !== undefined ? `Use ${equivalent} in ${selector}: ${choice}.` : `Drop ${parameter}, or switch to ${owners.join(" / ")} if that is what you meant.`
|
|
62137
|
+
});
|
|
62138
|
+
}
|
|
62139
|
+
return warnings;
|
|
62140
|
+
}
|
|
61901
62141
|
async function dispatchComposite(selector, routes, input, context) {
|
|
61902
62142
|
const choice = input[selector];
|
|
61903
62143
|
const route = typeof choice === "string" ? routes[choice] : undefined;
|
|
@@ -61916,16 +62156,46 @@ async function dispatchComposite(selector, routes, input, context) {
|
|
|
61916
62156
|
const structured = wrapped ? result.structuredContent : result;
|
|
61917
62157
|
const payload = isRecord(structured) ? structured : {};
|
|
61918
62158
|
const content = wrapped && Array.isArray(result.content) ? result.content : [{ type: "text", text: `${selector} ${String(choice)} completed` }];
|
|
62159
|
+
const ignored = foreignParameterWarnings(selector, String(choice), routes, rest);
|
|
62160
|
+
if (ignored.length === 0) {
|
|
62161
|
+
return {
|
|
62162
|
+
content,
|
|
62163
|
+
structuredContent: { [selector]: choice, ...payload }
|
|
62164
|
+
};
|
|
62165
|
+
}
|
|
62166
|
+
const asRecords = route.name !== undefined && RECORD_WARNING_OPERATIONS.has(route.name);
|
|
62167
|
+
const routedWarnings = Array.isArray(payload.warnings) ? {
|
|
62168
|
+
warnings: [
|
|
62169
|
+
...payload.warnings,
|
|
62170
|
+
...ignored.map((warning) => asRecords ? {
|
|
62171
|
+
kind: "parameter_ignored",
|
|
62172
|
+
message: warning.message,
|
|
62173
|
+
nextAction: warning.nextAction
|
|
62174
|
+
} : `${warning.message} ${warning.nextAction}`)
|
|
62175
|
+
]
|
|
62176
|
+
} : {};
|
|
61919
62177
|
return {
|
|
61920
|
-
content
|
|
61921
|
-
|
|
62178
|
+
content: [
|
|
62179
|
+
...content,
|
|
62180
|
+
{
|
|
62181
|
+
type: "text",
|
|
62182
|
+
text: ignored.map((warning) => `${warning.message} ${warning.nextAction}`).join(`
|
|
62183
|
+
`)
|
|
62184
|
+
}
|
|
62185
|
+
],
|
|
62186
|
+
structuredContent: { [selector]: choice, ...payload, ...routedWarnings }
|
|
61922
62187
|
};
|
|
61923
62188
|
}
|
|
61924
|
-
var SKILL_ROUTES, MODEL_ROUTES, skillsSpec, modelSpec;
|
|
62189
|
+
var EQUIVALENT_PARAMETERS, RECORD_WARNING_OPERATIONS, SKILL_ROUTES, MODEL_ROUTES, skillsSpec, modelSpec;
|
|
61925
62190
|
var init_composite = __esm(() => {
|
|
61926
62191
|
init_modeling();
|
|
61927
62192
|
init_semantic();
|
|
61928
62193
|
init_skills2();
|
|
62194
|
+
EQUIVALENT_PARAMETERS = {
|
|
62195
|
+
kb_suggest_predicates: { subjectKey: "subjectHint" },
|
|
62196
|
+
kb_model_requirement: { subjectHint: "subjectKey" }
|
|
62197
|
+
};
|
|
62198
|
+
RECORD_WARNING_OPERATIONS = new Set(["kb_model_requirement"]);
|
|
61929
62199
|
SKILL_ROUTES = {
|
|
61930
62200
|
list: skillsListSpec,
|
|
61931
62201
|
load: skillsLoadSpec,
|
|
@@ -64193,7 +64463,7 @@ var init_source_authoring = __esm(() => {
|
|
|
64193
64463
|
|
|
64194
64464
|
// ../cli/dist/operations/mutation/plan-apply-journal.js
|
|
64195
64465
|
import { createHash as createHash28, randomUUID as randomUUID3 } from "node:crypto";
|
|
64196
|
-
import { closeSync as closeSync3, existsSync as existsSync26, fsyncSync as fsyncSync2, mkdirSync as mkdirSync8, openSync as openSync3, readFileSync as readFileSync30, readdirSync as
|
|
64466
|
+
import { closeSync as closeSync3, existsSync as existsSync26, fsyncSync as fsyncSync2, mkdirSync as mkdirSync8, openSync as openSync3, readFileSync as readFileSync30, readdirSync as readdirSync9, renameSync as renameSync5, statSync as statSync10, unlinkSync as unlinkSync5, writeSync as writeSync2 } from "node:fs";
|
|
64197
64467
|
import path53 from "node:path";
|
|
64198
64468
|
function planApplyJournalId(planHash) {
|
|
64199
64469
|
return `plan-apply-${planHash.slice(0, 16).toLowerCase()}`;
|
|
@@ -64433,7 +64703,7 @@ function removeOrphanedStagedFiles(workspaceRoot, files) {
|
|
|
64433
64703
|
const prefix = `${path53.basename(absolute)}.kibi-stage-`;
|
|
64434
64704
|
let names;
|
|
64435
64705
|
try {
|
|
64436
|
-
names =
|
|
64706
|
+
names = readdirSync9(path53.dirname(absolute));
|
|
64437
64707
|
} catch {
|
|
64438
64708
|
continue;
|
|
64439
64709
|
}
|
|
@@ -64572,7 +64842,7 @@ async function recoverPendingPlanApplyJournals(context, options2) {
|
|
|
64572
64842
|
for (const directory of location.all) {
|
|
64573
64843
|
let names;
|
|
64574
64844
|
try {
|
|
64575
|
-
names =
|
|
64845
|
+
names = readdirSync9(directory);
|
|
64576
64846
|
} catch {
|
|
64577
64847
|
continue;
|
|
64578
64848
|
}
|
|
@@ -68895,7 +69165,7 @@ var init_staging = __esm(() => {
|
|
|
68895
69165
|
// ../cli/dist/commands/sync.js
|
|
68896
69166
|
import { execSync as execSync4 } from "node:child_process";
|
|
68897
69167
|
import { createHash as createHash32 } from "node:crypto";
|
|
68898
|
-
import { existsSync as existsSync34, mkdirSync as mkdirSync12, readFileSync as readFileSync40, readdirSync as
|
|
69168
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync12, readFileSync as readFileSync40, readdirSync as readdirSync10, renameSync as renameSync10, writeFileSync as writeFileSync15 } from "node:fs";
|
|
68899
69169
|
import * as path66 from "node:path";
|
|
68900
69170
|
function relationshipKey2(relationship) {
|
|
68901
69171
|
return `${relationship.type}\x00${relationship.from}\x00${relationship.to}`;
|
|
@@ -68940,7 +69210,7 @@ function trackedRelationshipFiles(workspaceRoot, relationshipsDir, recoverMissin
|
|
|
68940
69210
|
const pending = new Set;
|
|
68941
69211
|
const pendingRoot = path66.join(workspaceRoot, ".kb", "recovery", "pending-sources");
|
|
68942
69212
|
if (existsSync34(pendingRoot)) {
|
|
68943
|
-
for (const receiptName of
|
|
69213
|
+
for (const receiptName of readdirSync10(pendingRoot)) {
|
|
68944
69214
|
if (!receiptName.endsWith(".json"))
|
|
68945
69215
|
continue;
|
|
68946
69216
|
let receipt;
|
|
@@ -68982,7 +69252,7 @@ function trackedRelationshipFiles(workspaceRoot, relationshipsDir, recoverMissin
|
|
|
68982
69252
|
}
|
|
68983
69253
|
}
|
|
68984
69254
|
try {
|
|
68985
|
-
return
|
|
69255
|
+
return readdirSync10(relationshipsDir).filter((file) => file.endsWith(".yaml") || file.endsWith(".yml")).map((file) => path66.join(relationshipsDir, file)).filter((file) => {
|
|
68986
69256
|
const relative = path66.relative(workspaceRoot, file).replaceAll(path66.sep, "/");
|
|
68987
69257
|
return tracked.has(relative) || pending.has(relative);
|
|
68988
69258
|
}).sort();
|
|
@@ -70946,7 +71216,7 @@ ${KIBI_BIN_RESOLVER}
|
|
|
70946
71216
|
|
|
70947
71217
|
// ../cli/dist/commands/legacy-storage-migration.js
|
|
70948
71218
|
import { createHash as createHash35 } from "node:crypto";
|
|
70949
|
-
import { existsSync as existsSync37, mkdirSync as mkdirSync15, readFileSync as readFileSync43, readdirSync as
|
|
71219
|
+
import { existsSync as existsSync37, mkdirSync as mkdirSync15, readFileSync as readFileSync43, readdirSync as readdirSync12, renameSync as renameSync12, rmSync as rmSync5, statSync as statSync12, writeFileSync as writeFileSync18 } from "node:fs";
|
|
70950
71220
|
import * as path72 from "node:path";
|
|
70951
71221
|
function stripGlobToRoot(pattern) {
|
|
70952
71222
|
const normalized = pattern.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
@@ -71103,7 +71373,7 @@ function pruneEmptyLegacyDirs(cwd, plan) {
|
|
|
71103
71373
|
const ordered = [...roots].sort((a, b) => b.length - a.length);
|
|
71104
71374
|
for (const dir of ordered) {
|
|
71105
71375
|
try {
|
|
71106
|
-
if (statSync12(dir).isDirectory() &&
|
|
71376
|
+
if (statSync12(dir).isDirectory() && readdirSync12(dir).length === 0) {
|
|
71107
71377
|
rmSync5(dir, { recursive: true });
|
|
71108
71378
|
}
|
|
71109
71379
|
} catch {}
|
|
@@ -71115,7 +71385,7 @@ function rewritePendingSourceReceiptPaths(cwd, moves) {
|
|
|
71115
71385
|
return 0;
|
|
71116
71386
|
const moveByFrom = new Map(moves.map((move) => [move.from, move.to]));
|
|
71117
71387
|
let rewritten = 0;
|
|
71118
|
-
for (const name of
|
|
71388
|
+
for (const name of readdirSync12(pendingRoot)) {
|
|
71119
71389
|
if (!name.endsWith(".json"))
|
|
71120
71390
|
continue;
|
|
71121
71391
|
const receiptPath = path72.join(pendingRoot, name);
|
|
@@ -71412,7 +71682,7 @@ var init_entity_body_context2 = __esm(() => {
|
|
|
71412
71682
|
});
|
|
71413
71683
|
|
|
71414
71684
|
// ../cli/dist/public/ignore-policy.js
|
|
71415
|
-
import { existsSync as existsSync38, readFileSync as readFileSync44, readdirSync as
|
|
71685
|
+
import { existsSync as existsSync38, readFileSync as readFileSync44, readdirSync as readdirSync13 } from "node:fs";
|
|
71416
71686
|
import * as path73 from "node:path";
|
|
71417
71687
|
function readIgnoreFileLines(filePath) {
|
|
71418
71688
|
if (!existsSync38(filePath))
|
|
@@ -71437,7 +71707,7 @@ function createRepoIgnorePolicy(workspaceRoot) {
|
|
|
71437
71707
|
function walk(dirAbs) {
|
|
71438
71708
|
let entries;
|
|
71439
71709
|
try {
|
|
71440
|
-
entries =
|
|
71710
|
+
entries = readdirSync13(dirAbs, { withFileTypes: true });
|
|
71441
71711
|
} catch {
|
|
71442
71712
|
return;
|
|
71443
71713
|
}
|
|
@@ -74732,6 +75002,17 @@ var init_cli_operation_metadata = __esm(() => {
|
|
|
74732
75002
|
// ../cli/dist/cli-validate.js
|
|
74733
75003
|
var init_cli_validate = () => {};
|
|
74734
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
|
+
|
|
74735
75016
|
// ../cli/dist/public/operations/result-envelope.js
|
|
74736
75017
|
function record4(value) {
|
|
74737
75018
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -74823,23 +75104,33 @@ function extraFailedEffects(declared, data) {
|
|
|
74823
75104
|
function resultVersion(spec) {
|
|
74824
75105
|
return spec.resultVersion ?? `kibi.${spec.name}.v1`;
|
|
74825
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
|
+
}
|
|
74826
75112
|
function toKibiResult(spec, data, options2 = {}) {
|
|
74827
75113
|
const row = record4(data) ? data : undefined;
|
|
75114
|
+
const migrationRefused = row?.version === "kibi.migration-apply-result.v1" && row.outcome === "refused";
|
|
74828
75115
|
let status = options2.status;
|
|
74829
75116
|
if (!status) {
|
|
74830
75117
|
status = "success";
|
|
74831
75118
|
if (row?.status === "committed_with_repairs")
|
|
74832
75119
|
status = "committed_with_repairs";
|
|
74833
|
-
if (row?.status === "rejected")
|
|
75120
|
+
if (row?.status === "rejected" || migrationRefused)
|
|
74834
75121
|
status = "error";
|
|
74835
75122
|
}
|
|
74836
75123
|
const terminalError = row?.status === "rejected" ? {
|
|
74837
75124
|
code: "BOOTSTRAP_PLAN_REJECTED",
|
|
74838
75125
|
message: "Bootstrap stopped at a deterministic failure. Inspect actionResults for committed actions and re-plan from the current state.",
|
|
74839
75126
|
retryable: false
|
|
75127
|
+
} : migrationRefused ? {
|
|
75128
|
+
code: MIGRATION_PLAN_REFUSED,
|
|
75129
|
+
message: `Migration plan refused; nothing was changed. ${refusalDetail(row)}`.trim(),
|
|
75130
|
+
retryable: false
|
|
74840
75131
|
} : undefined;
|
|
74841
75132
|
const resultError = options2.error ?? terminalError;
|
|
74842
|
-
const outcome = effectOutcome(status, options2);
|
|
75133
|
+
const outcome = effectOutcome(status, migrationRefused && options2.attempted === undefined ? { ...options2, attempted: false } : options2);
|
|
74843
75134
|
return {
|
|
74844
75135
|
kibiProtocol: KIBI_PROTOCOL_VERSION,
|
|
74845
75136
|
operation: spec.name,
|
|
@@ -74888,6 +75179,9 @@ function appendPayloadCountField(fields, countKey, noun, payload) {
|
|
|
74888
75179
|
fields.result_summary = count === null ? `${noun} count unavailable` : `${count} ${noun}`;
|
|
74889
75180
|
}
|
|
74890
75181
|
var KIBI_PROTOCOL_VERSION = 1;
|
|
75182
|
+
var init_result_envelope = __esm(() => {
|
|
75183
|
+
init_migration_refusal();
|
|
75184
|
+
});
|
|
74891
75185
|
|
|
74892
75186
|
// ../cli/dist/cli-protocol.js
|
|
74893
75187
|
var import__2020, outputValidator;
|
|
@@ -74897,6 +75191,7 @@ var init_cli_protocol = __esm(() => {
|
|
|
74897
75191
|
init_cli_operation_metadata();
|
|
74898
75192
|
init_cli_validate();
|
|
74899
75193
|
init_engine_limits();
|
|
75194
|
+
init_result_envelope();
|
|
74900
75195
|
init_detached_snapshot();
|
|
74901
75196
|
import__2020 = __toESM(require__2020(), 1);
|
|
74902
75197
|
outputValidator = new import__2020.default({ strict: false, allErrors: true });
|
|
@@ -74905,6 +75200,7 @@ var init_cli_protocol = __esm(() => {
|
|
|
74905
75200
|
// ../cli/dist/public/diagnostic-usage.js
|
|
74906
75201
|
var RECEIPT_GAP_CODES;
|
|
74907
75202
|
var init_diagnostic_usage = __esm(() => {
|
|
75203
|
+
init_result_envelope();
|
|
74908
75204
|
RECEIPT_GAP_CODES = new Set([
|
|
74909
75205
|
"missing_proof_receipt",
|
|
74910
75206
|
"stale_proof_receipt",
|
|
@@ -75632,9 +75928,221 @@ var init_migrate = __esm(() => {
|
|
|
75632
75928
|
]);
|
|
75633
75929
|
});
|
|
75634
75930
|
|
|
75635
|
-
// ../cli/dist/
|
|
75636
|
-
import {
|
|
75931
|
+
// ../cli/dist/proof/integrations.js
|
|
75932
|
+
import { existsSync as existsSync41, readFileSync as readFileSync48 } from "node:fs";
|
|
75637
75933
|
import path79 from "node:path";
|
|
75934
|
+
function integrationsPath(workspaceRoot) {
|
|
75935
|
+
return path79.join(workspaceRoot, PROOF_INTEGRATIONS_PATH);
|
|
75936
|
+
}
|
|
75937
|
+
function proofIntegrationErrors(value) {
|
|
75938
|
+
const file = record5(value);
|
|
75939
|
+
if (!file)
|
|
75940
|
+
return [
|
|
75941
|
+
`${PROOF_INTEGRATIONS_PATH} must be an object with version and integrations`
|
|
75942
|
+
];
|
|
75943
|
+
const errors = [];
|
|
75944
|
+
if (file.version !== PROOF_INTEGRATION_VERSION)
|
|
75945
|
+
errors.push(`version must be ${PROOF_INTEGRATION_VERSION}; received ${JSON.stringify(file.version ?? null)}`);
|
|
75946
|
+
if (!Array.isArray(file.integrations) || file.integrations.length === 0) {
|
|
75947
|
+
errors.push("integrations must be a non-empty array");
|
|
75948
|
+
return errors;
|
|
75949
|
+
}
|
|
75950
|
+
const seen = new Set;
|
|
75951
|
+
file.integrations.forEach((entry, index) => {
|
|
75952
|
+
const row = record5(entry);
|
|
75953
|
+
const label = `integrations[${index}]`;
|
|
75954
|
+
if (!row) {
|
|
75955
|
+
errors.push(`${label} must be an object`);
|
|
75956
|
+
return;
|
|
75957
|
+
}
|
|
75958
|
+
if (!nonEmpty(row.id))
|
|
75959
|
+
errors.push(`${label}.id must be a non-empty string`);
|
|
75960
|
+
else {
|
|
75961
|
+
if (seen.has(String(row.id)))
|
|
75962
|
+
errors.push(`${label}.id duplicates '${String(row.id)}'`);
|
|
75963
|
+
seen.add(String(row.id));
|
|
75964
|
+
}
|
|
75965
|
+
if (!nonEmpty(row.producer))
|
|
75966
|
+
errors.push(`${label}.producer must be one of: ${PRODUCER_KINDS.join(", ")} (or a custom producer id)`);
|
|
75967
|
+
if (!Array.isArray(row.command) || row.command.length === 0 || !row.command.every((argument) => nonEmpty(argument)))
|
|
75968
|
+
errors.push(`${label}.command must be a non-empty argv array`);
|
|
75969
|
+
if (nonEmpty(row.producer) && (row.producer === "junit" || row.producer === "tap") && !nonEmpty(row.artifact))
|
|
75970
|
+
errors.push(`${label}.artifact is required for producer '${String(row.producer)}' (path of the native report to convert)`);
|
|
75971
|
+
if (row.targets !== undefined) {
|
|
75972
|
+
if (!Array.isArray(row.targets) || row.targets.length === 0 || !row.targets.every((target) => nonEmpty(target)))
|
|
75973
|
+
errors.push(`${label}.targets must be a non-empty array of target names`);
|
|
75974
|
+
}
|
|
75975
|
+
if (row.options !== undefined && !record5(row.options))
|
|
75976
|
+
errors.push(`${label}.options must be an object when present`);
|
|
75977
|
+
if (row.description !== undefined && !nonEmpty(row.description))
|
|
75978
|
+
errors.push(`${label}.description must be a non-empty string when present`);
|
|
75979
|
+
});
|
|
75980
|
+
return errors;
|
|
75981
|
+
}
|
|
75982
|
+
function loadProofIntegrations(workspaceRoot) {
|
|
75983
|
+
const filePath = integrationsPath(workspaceRoot);
|
|
75984
|
+
if (!existsSync41(filePath)) {
|
|
75985
|
+
return {
|
|
75986
|
+
available: false,
|
|
75987
|
+
error: `No proof integration configuration at ${PROOF_INTEGRATIONS_PATH}. Run kibi proof inspect --json and apply its integrationPlan with kb_apply_plan to configure one.`
|
|
75988
|
+
};
|
|
75989
|
+
}
|
|
75990
|
+
let parsed;
|
|
75991
|
+
try {
|
|
75992
|
+
parsed = JSON.parse(readFileSync48(filePath, "utf8"));
|
|
75993
|
+
} catch (error) {
|
|
75994
|
+
return {
|
|
75995
|
+
available: false,
|
|
75996
|
+
error: `${PROOF_INTEGRATIONS_PATH} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`
|
|
75997
|
+
};
|
|
75998
|
+
}
|
|
75999
|
+
const errors = proofIntegrationErrors(parsed);
|
|
76000
|
+
if (errors.length > 0)
|
|
76001
|
+
return {
|
|
76002
|
+
available: false,
|
|
76003
|
+
error: `Invalid ${PROOF_INTEGRATIONS_PATH}: ${errors.join("; ")}`
|
|
76004
|
+
};
|
|
76005
|
+
return { available: true, integrations: parsed };
|
|
76006
|
+
}
|
|
76007
|
+
function resolveIntegration(integrations, id) {
|
|
76008
|
+
return integrations.integrations.find((entry) => entry.id === id) ?? null;
|
|
76009
|
+
}
|
|
76010
|
+
function toExecution(integration) {
|
|
76011
|
+
return {
|
|
76012
|
+
id: integration.id,
|
|
76013
|
+
producer: integration.producer,
|
|
76014
|
+
...integration.producer_version !== undefined ? { producer_version: integration.producer_version } : {},
|
|
76015
|
+
command: integration.command,
|
|
76016
|
+
...integration.artifact !== undefined ? { artifact: integration.artifact } : {},
|
|
76017
|
+
...integration.targets !== undefined ? { targets: integration.targets } : {},
|
|
76018
|
+
...integration.options !== undefined ? { options: integration.options } : {}
|
|
76019
|
+
};
|
|
76020
|
+
}
|
|
76021
|
+
function record5(value) {
|
|
76022
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
76023
|
+
}
|
|
76024
|
+
function nonEmpty(value) {
|
|
76025
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
76026
|
+
}
|
|
76027
|
+
var PROOF_INTEGRATIONS_PATH = ".kb/proof/integrations.json", PRODUCER_KINDS;
|
|
76028
|
+
var init_integrations = __esm(() => {
|
|
76029
|
+
init_proof_protocol();
|
|
76030
|
+
PRODUCER_KINDS = [
|
|
76031
|
+
"command",
|
|
76032
|
+
"playwright",
|
|
76033
|
+
"junit",
|
|
76034
|
+
"tap"
|
|
76035
|
+
];
|
|
76036
|
+
});
|
|
76037
|
+
|
|
76038
|
+
// ../cli/dist/proof/integration-plan.js
|
|
76039
|
+
import { createHash as createHash39 } from "node:crypto";
|
|
76040
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync17, readFileSync as readFileSync49, renameSync as renameSync14, writeFileSync as writeFileSync20 } from "node:fs";
|
|
76041
|
+
import path80 from "node:path";
|
|
76042
|
+
function sha2563(bytes) {
|
|
76043
|
+
return createHash39("sha256").update(bytes).digest("hex");
|
|
76044
|
+
}
|
|
76045
|
+
function fileHash3(filePath) {
|
|
76046
|
+
try {
|
|
76047
|
+
return sha2563(readFileSync49(filePath));
|
|
76048
|
+
} catch {
|
|
76049
|
+
return null;
|
|
76050
|
+
}
|
|
76051
|
+
}
|
|
76052
|
+
function sourceHashes(root) {
|
|
76053
|
+
const hashes = {};
|
|
76054
|
+
for (const file of PROPOSAL_SOURCES) {
|
|
76055
|
+
const hash = fileHash3(path80.join(root, file));
|
|
76056
|
+
if (hash !== null)
|
|
76057
|
+
hashes[file] = hash;
|
|
76058
|
+
}
|
|
76059
|
+
return hashes;
|
|
76060
|
+
}
|
|
76061
|
+
function readIntegrationsFile(root) {
|
|
76062
|
+
try {
|
|
76063
|
+
const parsed = JSON.parse(readFileSync49(integrationsPath(root), "utf8"));
|
|
76064
|
+
return proofIntegrationErrors(parsed).length === 0 ? parsed : null;
|
|
76065
|
+
} catch {
|
|
76066
|
+
return null;
|
|
76067
|
+
}
|
|
76068
|
+
}
|
|
76069
|
+
function isRecord22(value) {
|
|
76070
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
76071
|
+
}
|
|
76072
|
+
function applyProofIntegrationAction(action, root) {
|
|
76073
|
+
const evidence = action.evidence;
|
|
76074
|
+
const integration = evidence.integration;
|
|
76075
|
+
if (evidence.path !== PROOF_INTEGRATIONS_PATH || evidence.mode !== "create" && evidence.mode !== "update" || !isRecord22(integration) || typeof integration.id !== "string")
|
|
76076
|
+
throw new MigrationActionRefusedError(`Proof integration action '${action.id}' is malformed; rerun kibi proof inspect for a new plan.`);
|
|
76077
|
+
const planned = isRecord22(evidence.sourceHashes) ? evidence.sourceHashes : {};
|
|
76078
|
+
const live = sourceHashes(root);
|
|
76079
|
+
const changed = [
|
|
76080
|
+
...new Set([...Object.keys(planned), ...Object.keys(live)])
|
|
76081
|
+
].filter((file) => planned[file] !== live[file]);
|
|
76082
|
+
if (changed.length > 0)
|
|
76083
|
+
throw new MigrationActionRefusedError(`Proof integration plan refused: ${changed.join(", ")} changed since planning; rerun kibi proof inspect and review the new plan.`);
|
|
76084
|
+
const filePath = integrationsPath(root);
|
|
76085
|
+
let integrations;
|
|
76086
|
+
if (evidence.mode === "create") {
|
|
76087
|
+
if (existsSync42(filePath))
|
|
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.`);
|
|
76089
|
+
integrations = [integration];
|
|
76090
|
+
} else {
|
|
76091
|
+
if (fileHash3(filePath) !== evidence.previousFileHash)
|
|
76092
|
+
throw new MigrationActionRefusedError(`Proof integration plan refused: ${PROOF_INTEGRATIONS_PATH} changed since planning; rerun kibi proof inspect --update ${integration.id}.`);
|
|
76093
|
+
const current = readIntegrationsFile(root);
|
|
76094
|
+
if (current === null)
|
|
76095
|
+
throw new MigrationActionRefusedError(`Proof integration plan refused: ${PROOF_INTEGRATIONS_PATH} is not a valid ${PROOF_INTEGRATION_VERSION} file.`);
|
|
76096
|
+
integrations = current.integrations.some((entry) => entry.id === integration.id) ? current.integrations.map((entry) => entry.id === integration.id ? integration : entry) : [...current.integrations, integration];
|
|
76097
|
+
}
|
|
76098
|
+
const file = { version: PROOF_INTEGRATION_VERSION, integrations };
|
|
76099
|
+
const errors = proofIntegrationErrors(file);
|
|
76100
|
+
if (errors.length > 0)
|
|
76101
|
+
throw new MigrationActionRefusedError(`Proof integration plan refused: the result would be invalid (${errors.join("; ")}).`);
|
|
76102
|
+
mkdirSync17(path80.dirname(filePath), { recursive: true });
|
|
76103
|
+
const temporary = `${filePath}.${process.pid}.tmp`;
|
|
76104
|
+
writeFileSync20(temporary, `${JSON.stringify(file, null, 2)}
|
|
76105
|
+
`, "utf8");
|
|
76106
|
+
renameSync14(temporary, filePath);
|
|
76107
|
+
}
|
|
76108
|
+
var PROOF_INTEGRATION_CONFIGURE = "proof_integration_configure", PROPOSAL_SOURCES;
|
|
76109
|
+
var init_integration_plan = __esm(() => {
|
|
76110
|
+
init_migration_refusal();
|
|
76111
|
+
init_migration_plan();
|
|
76112
|
+
init_proof_protocol();
|
|
76113
|
+
init_integrations();
|
|
76114
|
+
PROPOSAL_SOURCES = [
|
|
76115
|
+
"package.json",
|
|
76116
|
+
"bun.lock",
|
|
76117
|
+
"bun.lockb",
|
|
76118
|
+
"pnpm-lock.yaml",
|
|
76119
|
+
"yarn.lock",
|
|
76120
|
+
"playwright.config.ts",
|
|
76121
|
+
"playwright.config.mjs",
|
|
76122
|
+
"playwright.config.js",
|
|
76123
|
+
"vitest.config.ts",
|
|
76124
|
+
"vitest.config.mjs",
|
|
76125
|
+
"vitest.config.js",
|
|
76126
|
+
"jest.config.ts",
|
|
76127
|
+
"jest.config.mjs",
|
|
76128
|
+
"jest.config.js",
|
|
76129
|
+
"pytest.ini",
|
|
76130
|
+
"pyproject.toml",
|
|
76131
|
+
"setup.cfg",
|
|
76132
|
+
"tox.ini",
|
|
76133
|
+
"go.mod",
|
|
76134
|
+
"Cargo.toml",
|
|
76135
|
+
"pom.xml",
|
|
76136
|
+
"build.gradle",
|
|
76137
|
+
"build.gradle.kts",
|
|
76138
|
+
"Gemfile",
|
|
76139
|
+
"Rakefile"
|
|
76140
|
+
];
|
|
76141
|
+
});
|
|
76142
|
+
|
|
76143
|
+
// ../cli/dist/operations/planning/compile-intent.js
|
|
76144
|
+
import { createHash as createHash40 } from "node:crypto";
|
|
76145
|
+
import path81 from "node:path";
|
|
75638
76146
|
function compilePlanHash(plan) {
|
|
75639
76147
|
const { planHash: _ignored, ...body } = plan;
|
|
75640
76148
|
return hash2(body);
|
|
@@ -75643,7 +76151,7 @@ function text7(value) {
|
|
|
75643
76151
|
return typeof value === "string" ? value.trim() : "";
|
|
75644
76152
|
}
|
|
75645
76153
|
function hash2(value) {
|
|
75646
|
-
return
|
|
76154
|
+
return createHash40("sha256").update(canonicalize(value)).digest("hex");
|
|
75647
76155
|
}
|
|
75648
76156
|
function shortHash2(value, length = 8) {
|
|
75649
76157
|
return hash2(value).slice(0, length);
|
|
@@ -75671,7 +76179,7 @@ function requiredIntent(args) {
|
|
|
75671
76179
|
return intent;
|
|
75672
76180
|
}
|
|
75673
76181
|
function validateLocation(location) {
|
|
75674
|
-
if (!text7(location.path) ||
|
|
76182
|
+
if (!text7(location.path) || path81.isAbsolute(location.path) || location.path.split(/[\\/]/).includes("..")) {
|
|
75675
76183
|
throw new Error("Compile intent failed: sourceLocations.path must be workspace-relative");
|
|
75676
76184
|
}
|
|
75677
76185
|
}
|
|
@@ -75701,25 +76209,25 @@ function mergeSteps(steps) {
|
|
|
75701
76209
|
merged.set(key, {
|
|
75702
76210
|
...step,
|
|
75703
76211
|
...Array.isArray(step.relationships) ? {
|
|
75704
|
-
relationships: mergeRelationships(step.relationships.filter(
|
|
76212
|
+
relationships: mergeRelationships(step.relationships.filter(isRecord23))
|
|
75705
76213
|
} : {}
|
|
75706
76214
|
});
|
|
75707
76215
|
continue;
|
|
75708
76216
|
}
|
|
75709
76217
|
const properties = {
|
|
75710
|
-
...
|
|
75711
|
-
...
|
|
76218
|
+
...isRecord23(previous.properties) ? previous.properties : {},
|
|
76219
|
+
...isRecord23(step.properties) ? step.properties : {}
|
|
75712
76220
|
};
|
|
75713
76221
|
const relationships = mergeRelationships([
|
|
75714
|
-
...Array.isArray(previous.relationships) ? previous.relationships.filter(
|
|
75715
|
-
...Array.isArray(step.relationships) ? step.relationships.filter(
|
|
76222
|
+
...Array.isArray(previous.relationships) ? previous.relationships.filter(isRecord23) : [],
|
|
76223
|
+
...Array.isArray(step.relationships) ? step.relationships.filter(isRecord23) : []
|
|
75716
76224
|
]);
|
|
75717
76225
|
merged.set(key, { ...previous, ...step, properties, relationships });
|
|
75718
76226
|
}
|
|
75719
76227
|
const rank = (step) => ({ test: 1, scenario: 2, req: 3 })[text7(step.type)] ?? 0;
|
|
75720
76228
|
return [...merged.values()].sort((left, right) => rank(left) - rank(right) || text7(left.id).localeCompare(text7(right.id)));
|
|
75721
76229
|
}
|
|
75722
|
-
function
|
|
76230
|
+
function isRecord23(value) {
|
|
75723
76231
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
75724
76232
|
}
|
|
75725
76233
|
function withRequirementInventory(steps, requirementId, receipt, propositions) {
|
|
@@ -75740,7 +76248,7 @@ function withRequirementInventory(steps, requirementId, receipt, propositions) {
|
|
|
75740
76248
|
return steps.map((step) => {
|
|
75741
76249
|
if (text7(step.type) !== "req" || text7(step.id) !== requirementId)
|
|
75742
76250
|
return step;
|
|
75743
|
-
const properties =
|
|
76251
|
+
const properties = isRecord23(step.properties) ? step.properties : {};
|
|
75744
76252
|
return {
|
|
75745
76253
|
...step,
|
|
75746
76254
|
properties: {
|
|
@@ -75785,12 +76293,12 @@ function propositionDisposition2(proposition, suggestion) {
|
|
|
75785
76293
|
function sourceFilesFor(locations) {
|
|
75786
76294
|
return Array.from(new Set((locations ?? []).map((location) => location.path.trim()).filter(Boolean))).sort();
|
|
75787
76295
|
}
|
|
75788
|
-
async function
|
|
76296
|
+
async function sourceHashes2(context, locations) {
|
|
75789
76297
|
const hashes = {};
|
|
75790
76298
|
for (const relative of sourceFilesFor(locations)) {
|
|
75791
76299
|
try {
|
|
75792
|
-
const contents = context.fs ? await context.fs.readFile(
|
|
75793
|
-
hashes[relative] = contents === null ? null :
|
|
76300
|
+
const contents = context.fs ? await context.fs.readFile(path81.join(context.workspaceRoot, relative)) : null;
|
|
76301
|
+
hashes[relative] = contents === null ? null : createHash40("sha256").update(contents).digest("hex");
|
|
75794
76302
|
} catch {
|
|
75795
76303
|
hashes[relative] = null;
|
|
75796
76304
|
}
|
|
@@ -75812,12 +76320,12 @@ async function withDocumentTargets(context, prolog, steps, requirement, now) {
|
|
|
75812
76320
|
for (const step of steps) {
|
|
75813
76321
|
const type = text7(step.type);
|
|
75814
76322
|
const id = text7(step.id);
|
|
75815
|
-
const properties =
|
|
76323
|
+
const properties = isRecord23(step.properties) ? step.properties : {};
|
|
75816
76324
|
if (type === "symbol" || Object.keys(properties).length === 0) {
|
|
75817
76325
|
targeted.push(step);
|
|
75818
76326
|
continue;
|
|
75819
76327
|
}
|
|
75820
|
-
const stepDocument =
|
|
76328
|
+
const stepDocument = isRecord23(step.document) ? step.document : {};
|
|
75821
76329
|
const document = type === "req" && id === requirement.id ? {
|
|
75822
76330
|
...requirement.body !== undefined ? { body: requirement.body } : {},
|
|
75823
76331
|
...requirement.path !== undefined ? { path: requirement.path } : {}
|
|
@@ -75827,7 +76335,7 @@ async function withDocumentTargets(context, prolog, steps, requirement, now) {
|
|
|
75827
76335
|
type,
|
|
75828
76336
|
id,
|
|
75829
76337
|
properties,
|
|
75830
|
-
relationships: Array.isArray(step.relationships) ? step.relationships.filter(
|
|
76338
|
+
relationships: Array.isArray(step.relationships) ? step.relationships.filter(isRecord23) : [],
|
|
75831
76339
|
document
|
|
75832
76340
|
};
|
|
75833
76341
|
const { entity } = validateUpsertInput(input, now);
|
|
@@ -75846,7 +76354,7 @@ async function existingRequirementBody(context, source) {
|
|
|
75846
76354
|
if (!context.fs || !source.endsWith(".md"))
|
|
75847
76355
|
return;
|
|
75848
76356
|
try {
|
|
75849
|
-
const raw = await context.fs.readFile(
|
|
76357
|
+
const raw = await context.fs.readFile(path81.join(context.workspaceRoot, source));
|
|
75850
76358
|
return readAuthoredEntity(String(raw), source)?.body ?? undefined;
|
|
75851
76359
|
} catch {
|
|
75852
76360
|
return;
|
|
@@ -75857,12 +76365,12 @@ function generatedRequirementId(intent) {
|
|
|
75857
76365
|
}
|
|
75858
76366
|
function planWhatIfGoal(steps, now) {
|
|
75859
76367
|
return buildWhatIfAnalysisGoal(steps.map((step) => {
|
|
75860
|
-
const relationships = (Array.isArray(step.relationships) ? step.relationships.filter(
|
|
76368
|
+
const relationships = (Array.isArray(step.relationships) ? step.relationships.filter(isRecord23) : []).map((relationship) => ({
|
|
75861
76369
|
type: text7(relationship.type),
|
|
75862
76370
|
from: text7(relationship.from),
|
|
75863
76371
|
to: text7(relationship.to)
|
|
75864
76372
|
}));
|
|
75865
|
-
const properties =
|
|
76373
|
+
const properties = isRecord23(step.properties) ? step.properties : {};
|
|
75866
76374
|
if (Object.keys(properties).length === 0) {
|
|
75867
76375
|
return {
|
|
75868
76376
|
entity: { id: text7(step.id), type: text7(step.type) },
|
|
@@ -75894,7 +76402,7 @@ function whatIfWitness(witness) {
|
|
|
75894
76402
|
};
|
|
75895
76403
|
}
|
|
75896
76404
|
function whatIfWitnesses(value) {
|
|
75897
|
-
return (Array.isArray(value) ? value.filter(
|
|
76405
|
+
return (Array.isArray(value) ? value.filter(isRecord23) : []).map(whatIfWitness);
|
|
75898
76406
|
}
|
|
75899
76407
|
function parseWhatIfAnalysis(raw) {
|
|
75900
76408
|
if (typeof raw !== "string")
|
|
@@ -75911,7 +76419,7 @@ function parseWhatIfAnalysis(raw) {
|
|
|
75911
76419
|
const after = whatIfWitnesses(parsed);
|
|
75912
76420
|
return { after, introduced: after, removed: [], unchanged: [] };
|
|
75913
76421
|
}
|
|
75914
|
-
if (!
|
|
76422
|
+
if (!isRecord23(parsed))
|
|
75915
76423
|
return null;
|
|
75916
76424
|
return {
|
|
75917
76425
|
after: whatIfWitnesses(parsed.after),
|
|
@@ -75986,7 +76494,7 @@ function applyAcceptedProposals(steps, proposals) {
|
|
|
75986
76494
|
if (!existing)
|
|
75987
76495
|
continue;
|
|
75988
76496
|
const relationships = mergeRelationships([
|
|
75989
|
-
...Array.isArray(existing.relationships) ? existing.relationships.filter(
|
|
76497
|
+
...Array.isArray(existing.relationships) ? existing.relationships.filter(isRecord23) : [],
|
|
75990
76498
|
proposal.relationship
|
|
75991
76499
|
]);
|
|
75992
76500
|
byId.set(targetId, { ...existing, relationships });
|
|
@@ -76294,7 +76802,7 @@ async function executeCompileIntent(args, context) {
|
|
|
76294
76802
|
diagnostics.push("Change mode to update and supply requirementId to revise an existing requirement.");
|
|
76295
76803
|
const unresolved = propositions.some((proposition) => proposition.status === "ambiguous" || proposition.status === "ontology_gap") || diagnostics.some((entry) => entry.includes("unresolved") || entry.includes("not found") || entry.includes("different content"));
|
|
76296
76804
|
let statusValue = contradictions.outcome === "conflict" ? "blocked" : unresolved ? "needs_resolution" : "ready";
|
|
76297
|
-
const sourceHashMap = await
|
|
76805
|
+
const sourceHashMap = await sourceHashes2(context, args.sourceLocations);
|
|
76298
76806
|
let planSteps = stepsWithAcceptedProposals;
|
|
76299
76807
|
const sourceInput = {
|
|
76300
76808
|
excerpt: args.sourceExcerpt,
|
|
@@ -76375,21 +76883,21 @@ var init_compile_intent = __esm(() => {
|
|
|
76375
76883
|
});
|
|
76376
76884
|
|
|
76377
76885
|
// ../cli/dist/operations/planning/apply-plan.js
|
|
76378
|
-
import { createHash as
|
|
76379
|
-
import
|
|
76886
|
+
import { createHash as createHash41, randomUUID as randomUUID6 } from "node:crypto";
|
|
76887
|
+
import path82 from "node:path";
|
|
76380
76888
|
function text8(value) {
|
|
76381
76889
|
return typeof value === "string" ? value.trim() : "";
|
|
76382
76890
|
}
|
|
76383
|
-
function
|
|
76891
|
+
function isRecord24(value) {
|
|
76384
76892
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
76385
76893
|
}
|
|
76386
76894
|
function digest4(value) {
|
|
76387
|
-
return
|
|
76895
|
+
return createHash41("sha256").update(value).digest("hex");
|
|
76388
76896
|
}
|
|
76389
76897
|
function relationships(step) {
|
|
76390
76898
|
if (!Array.isArray(step.relationships))
|
|
76391
76899
|
return [];
|
|
76392
|
-
return step.relationships.filter(
|
|
76900
|
+
return step.relationships.filter(isRecord24).map((relationship) => {
|
|
76393
76901
|
const type = text8(relationship.type);
|
|
76394
76902
|
const from = text8(relationship.from);
|
|
76395
76903
|
const to = text8(relationship.to);
|
|
@@ -76405,8 +76913,8 @@ function asUpsert(step) {
|
|
|
76405
76913
|
throw new Error(`Apply plan failed: unsupported step entity type '${type}'`);
|
|
76406
76914
|
if (!id)
|
|
76407
76915
|
throw new Error("Apply plan failed: every step needs an entity id");
|
|
76408
|
-
const properties =
|
|
76409
|
-
const document =
|
|
76916
|
+
const properties = isRecord24(step.properties) ? step.properties : {};
|
|
76917
|
+
const document = isRecord24(step.document) ? {
|
|
76410
76918
|
...typeof step.document.path === "string" ? { path: step.document.path } : {},
|
|
76411
76919
|
...typeof step.document.body === "string" ? { body: step.document.body } : {}
|
|
76412
76920
|
} : undefined;
|
|
@@ -76419,7 +76927,7 @@ function asUpsert(step) {
|
|
|
76419
76927
|
};
|
|
76420
76928
|
}
|
|
76421
76929
|
function validateCompilePlanShape(args) {
|
|
76422
|
-
if (!
|
|
76930
|
+
if (!isRecord24(args.plan))
|
|
76423
76931
|
throw new Error("Apply plan failed: plan must be an object");
|
|
76424
76932
|
if (args.plan.version !== "kibi.compile-plan.v1")
|
|
76425
76933
|
throw new Error("Apply plan failed: unsupported plan version");
|
|
@@ -76441,7 +76949,7 @@ function isBootstrapApplyArgs(args) {
|
|
|
76441
76949
|
return "plan" in args && args.plan.version === "kibi.bootstrap-plan.v1";
|
|
76442
76950
|
}
|
|
76443
76951
|
function assertSourceWriteStaysInWorkspace(root, absolute, writePath) {
|
|
76444
|
-
if (absolute !== root && !absolute.startsWith(`${root}${
|
|
76952
|
+
if (absolute !== root && !absolute.startsWith(`${root}${path82.sep}`)) {
|
|
76445
76953
|
throw new Error(`Apply plan failed: sourceWrites.path escapes workspace: ${writePath}`);
|
|
76446
76954
|
}
|
|
76447
76955
|
}
|
|
@@ -76459,7 +76967,7 @@ function orderBootstrapActions(actions, completed = new Set) {
|
|
|
76459
76967
|
for (const action of actions) {
|
|
76460
76968
|
if (!action.id || byId.has(action.id))
|
|
76461
76969
|
throw new Error("Bootstrap apply failed: action IDs must be unique");
|
|
76462
|
-
if (action.kind !== "upsert" || !
|
|
76970
|
+
if (action.kind !== "upsert" || !isRecord24(action.payload))
|
|
76463
76971
|
throw new Error(`Bootstrap apply failed: action '${action.id}' is invalid`);
|
|
76464
76972
|
byId.set(action.id, action);
|
|
76465
76973
|
}
|
|
@@ -76548,7 +77056,7 @@ function validateEntityDeletionPlan(args) {
|
|
|
76548
77056
|
throw new Error("Entity deletion apply failed: approvedPlanHash does not match planHash");
|
|
76549
77057
|
}
|
|
76550
77058
|
const { planHash: _ignored, ...body } = args.plan;
|
|
76551
|
-
if (
|
|
77059
|
+
if (createHash41("sha256").update(JSON.stringify(body)).digest("hex") !== args.plan.planHash) {
|
|
76552
77060
|
throw new Error("Entity deletion apply failed: planHash does not match the canonical plan body");
|
|
76553
77061
|
}
|
|
76554
77062
|
if (!Array.isArray(args.plan.entityIds) || args.plan.entityIds.length === 0) {
|
|
@@ -76559,7 +77067,7 @@ function validateEntityDeletionPlan(args) {
|
|
|
76559
77067
|
}
|
|
76560
77068
|
}
|
|
76561
77069
|
function validateMigrationPlanShape(args) {
|
|
76562
|
-
if (!
|
|
77070
|
+
if (!isRecord24(args.plan))
|
|
76563
77071
|
throw new Error("Migration apply failed: plan must be an object");
|
|
76564
77072
|
if (args.plan.version !== "kibi.migration-plan.v2")
|
|
76565
77073
|
throw new Error("Migration apply failed: unsupported plan version");
|
|
@@ -76621,13 +77129,13 @@ function topologicalActions(actions) {
|
|
|
76621
77129
|
async function validateSources(context, sourceHashes) {
|
|
76622
77130
|
let checked = 0;
|
|
76623
77131
|
for (const [relative, expected] of Object.entries(sourceHashes)) {
|
|
76624
|
-
if (!relative ||
|
|
77132
|
+
if (!relative || path82.isAbsolute(relative) || relative.split(/[\\/]/).includes(".."))
|
|
76625
77133
|
throw new Error("Apply plan failed: source hash paths must be workspace-relative");
|
|
76626
77134
|
if (!context.fs)
|
|
76627
77135
|
throw new Error("Apply plan failed: source hashes require a filesystem-capable runtime");
|
|
76628
77136
|
let actual;
|
|
76629
77137
|
try {
|
|
76630
|
-
actual = digest4(await context.fs.readFile(
|
|
77138
|
+
actual = digest4(await context.fs.readFile(path82.join(context.workspaceRoot, relative)));
|
|
76631
77139
|
} catch {
|
|
76632
77140
|
actual = null;
|
|
76633
77141
|
}
|
|
@@ -76638,19 +77146,19 @@ async function validateSources(context, sourceHashes) {
|
|
|
76638
77146
|
return checked;
|
|
76639
77147
|
}
|
|
76640
77148
|
async function resolveSourceWriteTarget(workspaceRoot, fsPort, write) {
|
|
76641
|
-
if (!write.path ||
|
|
77149
|
+
if (!write.path || path82.isAbsolute(write.path) || write.path.split(/[\\/]/).includes("..")) {
|
|
76642
77150
|
throw new Error(`Apply plan failed: sourceWrites.path must be workspace-relative: ${write.path}`);
|
|
76643
77151
|
}
|
|
76644
|
-
const absolute =
|
|
76645
|
-
const root =
|
|
77152
|
+
const absolute = path82.resolve(workspaceRoot, write.path);
|
|
77153
|
+
const root = path82.resolve(workspaceRoot);
|
|
76646
77154
|
assertSourceWriteStaysInWorkspace(root, absolute, write.path);
|
|
76647
|
-
const relative =
|
|
77155
|
+
const relative = path82.relative(root, absolute).split(path82.sep).join("/");
|
|
76648
77156
|
if (relative === ".kb" || isDerivedKbPath(relative)) {
|
|
76649
77157
|
throw new Error("Apply plan failed: sourceWrites.path cannot target Kibi's derived .kb runtime trees");
|
|
76650
77158
|
}
|
|
76651
77159
|
const realRoot = canonicalFilesystemPath(root);
|
|
76652
77160
|
const realExisting = canonicalFilesystemPath(absolute);
|
|
76653
|
-
if (realExisting !== realRoot && !realExisting.startsWith(`${realRoot}${
|
|
77161
|
+
if (realExisting !== realRoot && !realExisting.startsWith(`${realRoot}${path82.sep}`)) {
|
|
76654
77162
|
throw new Error(`Apply plan failed: sourceWrites.path follows a symlink outside the workspace: ${write.path}`);
|
|
76655
77163
|
}
|
|
76656
77164
|
const existing = await fsPort.readFile(absolute).catch(() => {
|
|
@@ -76681,7 +77189,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
|
|
|
76681
77189
|
throw new Error("Apply plan failed: sourceWrites require a filesystem-capable runtime");
|
|
76682
77190
|
}
|
|
76683
77191
|
const fsPort = context.fs;
|
|
76684
|
-
const journalPath =
|
|
77192
|
+
const journalPath = path82.join(context.workspaceRoot, ".kb", "recovery", `source-writes-${planHash.slice(0, 16)}.json`);
|
|
76685
77193
|
const journalId = `source-writes-${planHash.slice(0, 16)}`;
|
|
76686
77194
|
const sameEntries = (entries) => entries.length === writes.length && entries.every((entry) => writes.some((write) => write.path === entry.path && (write.mode ?? "write") === entry.mode && write.beforeHash === entry.beforeHash && write.afterHash === entry.afterHash));
|
|
76687
77195
|
const readJournal = async () => {
|
|
@@ -76704,7 +77212,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
|
|
|
76704
77212
|
let allAfter = true;
|
|
76705
77213
|
for (const entry of prior.entries) {
|
|
76706
77214
|
try {
|
|
76707
|
-
const current = await context.fs.readFile(
|
|
77215
|
+
const current = await context.fs.readFile(path82.resolve(context.workspaceRoot, entry.path));
|
|
76708
77216
|
if (entry.afterHash === null || digest4(current) !== entry.afterHash) {
|
|
76709
77217
|
allAfter = false;
|
|
76710
77218
|
}
|
|
@@ -76726,7 +77234,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
|
|
|
76726
77234
|
}
|
|
76727
77235
|
if (prior && (prior.state === "prepared" || prior.state === "publishing_sources")) {
|
|
76728
77236
|
for (const entry of prior.entries) {
|
|
76729
|
-
const absolute =
|
|
77237
|
+
const absolute = path82.resolve(context.workspaceRoot, entry.path);
|
|
76730
77238
|
let current;
|
|
76731
77239
|
try {
|
|
76732
77240
|
current = await context.fs.readFile(absolute);
|
|
@@ -76759,7 +77267,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
|
|
|
76759
77267
|
const { absolute, existing, mode } = await resolveSourceWriteTarget(context.workspaceRoot, fsPort, write);
|
|
76760
77268
|
originals.push({ absolute, body: existing });
|
|
76761
77269
|
paths.push(write.path);
|
|
76762
|
-
const stageBase =
|
|
77270
|
+
const stageBase = path82.join(context.workspaceRoot, ".kb", "recovery", `${journalId}-${entries.length}`);
|
|
76763
77271
|
entries.push({
|
|
76764
77272
|
path: write.path,
|
|
76765
77273
|
mode,
|
|
@@ -76770,7 +77278,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
|
|
|
76770
77278
|
afterStage: `${stageBase}.after`
|
|
76771
77279
|
});
|
|
76772
77280
|
}
|
|
76773
|
-
await context.fs.mkdir(
|
|
77281
|
+
await context.fs.mkdir(path82.dirname(journalPath));
|
|
76774
77282
|
for (let index = 0;index < writes.length; index += 1) {
|
|
76775
77283
|
const original = originals[index];
|
|
76776
77284
|
const entry = entries[index];
|
|
@@ -76791,7 +77299,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
|
|
|
76791
77299
|
const write = writes[index];
|
|
76792
77300
|
if (!absolute || !write)
|
|
76793
77301
|
continue;
|
|
76794
|
-
await context.fs.mkdir(
|
|
77302
|
+
await context.fs.mkdir(path82.dirname(absolute));
|
|
76795
77303
|
await context.fs.writeFile(journalPath, `${JSON.stringify({ version: 1, planHash, state: "publishing_sources", entries }, null, 2)}
|
|
76796
77304
|
`);
|
|
76797
77305
|
if ((write.mode ?? "write") === "delete") {
|
|
@@ -76843,7 +77351,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
|
|
|
76843
77351
|
} catch {}
|
|
76844
77352
|
}
|
|
76845
77353
|
try {
|
|
76846
|
-
await context.fs.mkdir(
|
|
77354
|
+
await context.fs.mkdir(path82.dirname(journalPath));
|
|
76847
77355
|
await context.fs.writeFile(journalPath, `${JSON.stringify({ version: 1, planHash, state: "rolled_back", entries }, null, 2)}
|
|
76848
77356
|
`);
|
|
76849
77357
|
} catch {}
|
|
@@ -76860,7 +77368,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
|
|
|
76860
77368
|
async function markSourceJournal(context, journalId, state) {
|
|
76861
77369
|
if (!journalId || !context.fs)
|
|
76862
77370
|
return;
|
|
76863
|
-
const journalPath =
|
|
77371
|
+
const journalPath = path82.join(context.workspaceRoot, ".kb", "recovery", `${journalId}.json`);
|
|
76864
77372
|
try {
|
|
76865
77373
|
const current = JSON.parse(await context.fs.readFile(journalPath));
|
|
76866
77374
|
await context.fs.writeFile(journalPath, `${JSON.stringify({ ...current, state }, null, 2)}
|
|
@@ -76875,7 +77383,7 @@ async function executeSourceRecovery(args, context, onCommitted = () => {
|
|
|
76875
77383
|
if (!/^[A-Za-z0-9._-]+$/.test(args.recoveryJournalId)) {
|
|
76876
77384
|
throw new Error("Source recovery journal ID is invalid");
|
|
76877
77385
|
}
|
|
76878
|
-
const journalPath =
|
|
77386
|
+
const journalPath = path82.join(context.workspaceRoot, ".kb", "recovery", `${args.recoveryJournalId}.json`);
|
|
76879
77387
|
const journal = JSON.parse(await context.fs.readFile(journalPath));
|
|
76880
77388
|
if (journal.version !== 1 || typeof journal.planHash !== "string" || !Array.isArray(journal.entries) || !["sources_committed", "compiled_published", "repair_required"].includes(journal.state ?? "")) {
|
|
76881
77389
|
throw new Error("Source recovery requires a committed or repair_required journal");
|
|
@@ -76952,7 +77460,7 @@ async function assertBootstrapPlanCurrent(args, operationContext) {
|
|
|
76952
77460
|
async function preflightApplyPlan(args, context) {
|
|
76953
77461
|
if (!("plan" in args))
|
|
76954
77462
|
return;
|
|
76955
|
-
if (!
|
|
77463
|
+
if (!isRecord24(args.plan))
|
|
76956
77464
|
throw new Error("Apply plan failed: plan must be an object");
|
|
76957
77465
|
if (typeof args.approvedPlanHash !== "string" || !/^[a-f0-9]{64}$/i.test(args.approvedPlanHash))
|
|
76958
77466
|
throw new Error("Apply plan failed: approvedPlanHash must be the SHA-256 planHash returned with the plan");
|
|
@@ -76991,7 +77499,7 @@ async function executeBootstrapPlan(args, context, recovery = false, remainingAc
|
|
|
76991
77499
|
if (!status)
|
|
76992
77500
|
throw new Error("Bootstrap apply failed: status returned no payload");
|
|
76993
77501
|
const journalId = `bootstrap-${args.plan.planHash.slice(0, 16)}`;
|
|
76994
|
-
const journalPath =
|
|
77502
|
+
const journalPath = path82.join(context.workspaceRoot, ".kb", "recovery", `${journalId}.json`);
|
|
76995
77503
|
if (!recovery && context.fs) {
|
|
76996
77504
|
try {
|
|
76997
77505
|
await context.fs.readFile(journalPath);
|
|
@@ -77024,7 +77532,7 @@ async function executeBootstrapPlan(args, context, recovery = false, remainingAc
|
|
|
77024
77532
|
const writeJournal = async (state, activeActionId, currentCheckpoint = lastCheckpoint) => {
|
|
77025
77533
|
if (!context.fs)
|
|
77026
77534
|
return;
|
|
77027
|
-
await context.fs.mkdir(
|
|
77535
|
+
await context.fs.mkdir(path82.dirname(journalPath));
|
|
77028
77536
|
await context.fs.writeFile(journalPath, `${JSON.stringify({
|
|
77029
77537
|
version: 2,
|
|
77030
77538
|
kind: "bootstrap",
|
|
@@ -77294,7 +77802,7 @@ async function dispatchApplyPlan(args, context, onCommitted, recovered) {
|
|
|
77294
77802
|
throw new Error("Bootstrap recovery requires a filesystem-capable runtime");
|
|
77295
77803
|
if (!/^bootstrap-[a-f0-9]{16}$/.test(args.recoveryJournalId))
|
|
77296
77804
|
throw new Error("Bootstrap recovery journal ID is invalid");
|
|
77297
|
-
const journalPath =
|
|
77805
|
+
const journalPath = path82.join(context.workspaceRoot, ".kb", "recovery", `${args.recoveryJournalId}.json`);
|
|
77298
77806
|
const journal = JSON.parse(await context.fs.readFile(journalPath));
|
|
77299
77807
|
if (journal.version !== 2 || journal.kind !== "bootstrap" || !journal.plan)
|
|
77300
77808
|
throw new Error("Bootstrap recovery journal is invalid");
|
|
@@ -77478,7 +77986,7 @@ async function planFileWrites(context, prolog, fsPort, sourceWrites, steps, now)
|
|
|
77478
77986
|
const relative = canonicalSourcePath(context, step.input, step.entity, existing);
|
|
77479
77987
|
let file = files.get(relative);
|
|
77480
77988
|
if (file === undefined) {
|
|
77481
|
-
const existingBytes = await fsPort.readFile(
|
|
77989
|
+
const existingBytes = await fsPort.readFile(path82.join(workspaceRoot, relative)).catch(() => {
|
|
77482
77990
|
return;
|
|
77483
77991
|
});
|
|
77484
77992
|
const before = existingBytes ?? null;
|
|
@@ -77503,8 +78011,8 @@ async function planFileWrites(context, prolog, fsPort, sourceWrites, steps, now)
|
|
|
77503
78011
|
file.after = after;
|
|
77504
78012
|
file.afterHash = contentHash(after);
|
|
77505
78013
|
}
|
|
77506
|
-
const root =
|
|
77507
|
-
const kbRoot =
|
|
78014
|
+
const root = path82.resolve(workspaceRoot);
|
|
78015
|
+
const kbRoot = path82.join(workspaceRoot, ".kb");
|
|
77508
78016
|
const createdAt = now.toISOString();
|
|
77509
78017
|
for (const step of steps) {
|
|
77510
78018
|
for (const relationship of step.relationships) {
|
|
@@ -77515,7 +78023,7 @@ async function planFileWrites(context, prolog, fsPort, sourceWrites, steps, now)
|
|
|
77515
78023
|
continue;
|
|
77516
78024
|
const shardPath = computeShardPath(kbRoot, from);
|
|
77517
78025
|
assertRelationshipShardContained(workspaceRoot, shardPath);
|
|
77518
|
-
const relative =
|
|
78026
|
+
const relative = path82.relative(root, path82.resolve(shardPath)).split(path82.sep).join("/");
|
|
77519
78027
|
let file = files.get(relative);
|
|
77520
78028
|
if (file === undefined) {
|
|
77521
78029
|
const existing = await fsPort.readFile(shardPath).catch(() => null);
|
|
@@ -77967,7 +78475,7 @@ function withRecoveryReport(result, recovered) {
|
|
|
77967
78475
|
action: recovery.action,
|
|
77968
78476
|
restoredPaths: recovery.restoredPaths
|
|
77969
78477
|
}));
|
|
77970
|
-
if (
|
|
78478
|
+
if (isRecord24(structured.validationSummary)) {
|
|
77971
78479
|
const summary = structured.validationSummary;
|
|
77972
78480
|
return {
|
|
77973
78481
|
content,
|
|
@@ -78000,7 +78508,7 @@ async function applyingBootstrapJournal(args, context) {
|
|
|
78000
78508
|
return;
|
|
78001
78509
|
if (!/^bootstrap-[a-f0-9]{16}$/.test(args.recoveryJournalId))
|
|
78002
78510
|
return;
|
|
78003
|
-
const journalPath =
|
|
78511
|
+
const journalPath = path82.join(context.workspaceRoot, ".kb", "recovery", `${args.recoveryJournalId}.json`);
|
|
78004
78512
|
try {
|
|
78005
78513
|
const journal = JSON.parse(await context.fs.readFile(journalPath));
|
|
78006
78514
|
return journal.kind === "bootstrap" && journal.state === "applying" ? journalPath : undefined;
|
|
@@ -78087,6 +78595,8 @@ async function applyMigrationPlan(args, context, onCommitted = () => {
|
|
|
78087
78595
|
}
|
|
78088
78596
|
const results = [];
|
|
78089
78597
|
let failed = false;
|
|
78598
|
+
let refusals = 0;
|
|
78599
|
+
let failures = 0;
|
|
78090
78600
|
for (const action of actions) {
|
|
78091
78601
|
if (failed) {
|
|
78092
78602
|
results.push({
|
|
@@ -78106,6 +78616,9 @@ async function applyMigrationPlan(args, context, onCommitted = () => {
|
|
|
78106
78616
|
});
|
|
78107
78617
|
} catch (error) {
|
|
78108
78618
|
failed = true;
|
|
78619
|
+
failures += 1;
|
|
78620
|
+
if (error instanceof MigrationActionRefusedError)
|
|
78621
|
+
refusals += 1;
|
|
78109
78622
|
results.push({
|
|
78110
78623
|
actionId: action.id,
|
|
78111
78624
|
outcome: "failed",
|
|
@@ -78152,7 +78665,7 @@ async function applyMigrationPlan(args, context, onCommitted = () => {
|
|
|
78152
78665
|
});
|
|
78153
78666
|
}
|
|
78154
78667
|
}
|
|
78155
|
-
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";
|
|
78156
78669
|
const kbState = finalStatus.branchAttachment?.migrationRequired ? "legacy_compat" : finalStatus.syncState === "stale" ? "stale" : finalStatus.dirty ? "dirty" : finalStatus.syncState === "fresh" ? "clean_fresh" : "not_evaluated";
|
|
78157
78670
|
const snapshotState = finalStatus.proofSnapshotAvailable === false ? "unavailable" : finalStatus.proofSnapshotDirty === true ? "dirty" : finalStatus.proofSnapshotDirty === false ? "fresh" : "not_evaluated";
|
|
78158
78671
|
const proven = coverageSummary?.proofProven;
|
|
@@ -78173,7 +78686,7 @@ async function applyMigrationPlan(args, context, onCommitted = () => {
|
|
|
78173
78686
|
],
|
|
78174
78687
|
...remainingPlan !== undefined ? { remainingPlan } : {},
|
|
78175
78688
|
closeout: {
|
|
78176
|
-
taskOutcome: outcome === "applied" ? "complete" : outcome === "reconciliation_required" ? "blocked" : "interim",
|
|
78689
|
+
taskOutcome: outcome === "applied" ? "complete" : outcome === "reconciliation_required" || outcome === "refused" ? "blocked" : "interim",
|
|
78177
78690
|
kbState,
|
|
78178
78691
|
snapshotState,
|
|
78179
78692
|
proofState,
|
|
@@ -78184,7 +78697,7 @@ async function applyMigrationPlan(args, context, onCommitted = () => {
|
|
|
78184
78697
|
content: [
|
|
78185
78698
|
{
|
|
78186
78699
|
type: "text",
|
|
78187
|
-
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)}.`
|
|
78188
78701
|
}
|
|
78189
78702
|
],
|
|
78190
78703
|
structuredContent: payload
|
|
@@ -78214,6 +78727,14 @@ async function applyMigrationAction(action, context) {
|
|
|
78214
78727
|
case "missing_exact_branch_store":
|
|
78215
78728
|
await branchEnsureCommand({ workspaceRoot: context.workspaceRoot });
|
|
78216
78729
|
return;
|
|
78730
|
+
case BRANCH_STORE_NOT_COMPILED: {
|
|
78731
|
+
const result = await syncCommand({
|
|
78732
|
+
workspaceRoot: context.workspaceRoot
|
|
78733
|
+
});
|
|
78734
|
+
if (!result.success)
|
|
78735
|
+
throw new Error("Compiling the branch store (kibi sync) did not complete successfully.");
|
|
78736
|
+
return;
|
|
78737
|
+
}
|
|
78217
78738
|
case "damaged_exact_branch_store":
|
|
78218
78739
|
await branchRecoverCommand({
|
|
78219
78740
|
apply: true,
|
|
@@ -78243,21 +78764,24 @@ async function applyMigrationAction(action, context) {
|
|
|
78243
78764
|
case PREDICATE_SCHEMA_ALIGNMENT_CODE:
|
|
78244
78765
|
await applyPredicateSchemaAlignment(action, context);
|
|
78245
78766
|
return;
|
|
78767
|
+
case PROOF_INTEGRATION_CONFIGURE:
|
|
78768
|
+
applyProofIntegrationAction(action, context.workspaceRoot);
|
|
78769
|
+
return;
|
|
78246
78770
|
default:
|
|
78247
78771
|
if (SCHEMA6_AUTOMATIC_CODES.has(action.code)) {
|
|
78248
78772
|
await applySchema6MigrationAction(action, context);
|
|
78249
78773
|
return;
|
|
78250
78774
|
}
|
|
78251
|
-
throw new
|
|
78775
|
+
throw new MigrationActionRefusedError(`Migration action '${action.code}' has no automatic executor.`);
|
|
78252
78776
|
}
|
|
78253
78777
|
}
|
|
78254
78778
|
async function applyPredicateSchemaAlignment(action, context) {
|
|
78255
78779
|
const invocation = action.invocation;
|
|
78256
78780
|
if (invocation.kind !== "operation" || invocation.name !== "kb_upsert")
|
|
78257
|
-
throw new
|
|
78781
|
+
throw new MigrationActionRefusedError("Predicate schema alignment requires its planned kb_upsert invocation.");
|
|
78258
78782
|
const input = asUpsert(invocation.input);
|
|
78259
78783
|
if (input.type !== "fact")
|
|
78260
|
-
throw new
|
|
78784
|
+
throw new MigrationActionRefusedError("Predicate schema alignment only rewrites fact entities.");
|
|
78261
78785
|
const prolog = context.prolog ?? await context.ensureProlog?.();
|
|
78262
78786
|
if (!prolog)
|
|
78263
78787
|
throw new Error("Predicate schema alignment requires a Prolog runtime.");
|
|
@@ -78267,9 +78791,9 @@ async function applyPredicateSchemaAlignment(action, context) {
|
|
|
78267
78791
|
const currentNamespace = typeof current?.predicate_namespace === "string" && current.predicate_namespace !== "" ? current.predicate_namespace : "default";
|
|
78268
78792
|
const currentArgs = Array.isArray(current?.predicate_args) ? current.predicate_args : [];
|
|
78269
78793
|
const rewrites = Array.isArray(evidence.rewrites) ? evidence.rewrites : [];
|
|
78270
|
-
const unchanged = current !== undefined && current.fact_kind === "predicate" && currentNamespace === evidence.namespace && rewrites.every((rewrite) =>
|
|
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);
|
|
78271
78795
|
if (!unchanged)
|
|
78272
|
-
throw new
|
|
78796
|
+
throw new MigrationActionRefusedError(`Predicate fact ${input.id} changed since planning; rerun kibi check and approve the new plan.`);
|
|
78273
78797
|
await executeUpsert(input, operationContext);
|
|
78274
78798
|
}
|
|
78275
78799
|
var PLAN_APPLY_RESULT_VERSION = "kibi.plan-apply-result.v1", ENTITY_TYPES4;
|
|
@@ -78278,11 +78802,13 @@ var init_apply_plan = __esm(() => {
|
|
|
78278
78802
|
init_branch();
|
|
78279
78803
|
init_migrate();
|
|
78280
78804
|
init_sync();
|
|
78805
|
+
init_integration_plan();
|
|
78281
78806
|
init_discovery_entities();
|
|
78282
78807
|
init_discovery_executors();
|
|
78283
78808
|
init_migration_plan();
|
|
78284
78809
|
init_migration_plan();
|
|
78285
78810
|
init_shards();
|
|
78811
|
+
init_branch_store();
|
|
78286
78812
|
init_canonical_path();
|
|
78287
78813
|
init_kb_paths();
|
|
78288
78814
|
init_types();
|
|
@@ -78295,6 +78821,7 @@ var init_apply_plan = __esm(() => {
|
|
|
78295
78821
|
init_upsert();
|
|
78296
78822
|
init_workspace_mutation_lock();
|
|
78297
78823
|
init_compile_intent();
|
|
78824
|
+
init_migration_refusal();
|
|
78298
78825
|
ENTITY_TYPES4 = new Set([
|
|
78299
78826
|
"req",
|
|
78300
78827
|
"scenario",
|
|
@@ -78719,113 +79246,6 @@ function evaluateContractAgainstRun(artifact, contract) {
|
|
|
78719
79246
|
}
|
|
78720
79247
|
var MAX_ATTRIBUTED_MEMBERS = 5;
|
|
78721
79248
|
|
|
78722
|
-
// ../cli/dist/proof/integrations.js
|
|
78723
|
-
import { existsSync as existsSync41, readFileSync as readFileSync48 } from "node:fs";
|
|
78724
|
-
import path81 from "node:path";
|
|
78725
|
-
function integrationsPath(workspaceRoot) {
|
|
78726
|
-
return path81.join(workspaceRoot, PROOF_INTEGRATIONS_PATH);
|
|
78727
|
-
}
|
|
78728
|
-
function proofIntegrationErrors(value) {
|
|
78729
|
-
const file = record5(value);
|
|
78730
|
-
if (!file)
|
|
78731
|
-
return [
|
|
78732
|
-
`${PROOF_INTEGRATIONS_PATH} must be an object with version and integrations`
|
|
78733
|
-
];
|
|
78734
|
-
const errors = [];
|
|
78735
|
-
if (file.version !== PROOF_INTEGRATION_VERSION)
|
|
78736
|
-
errors.push(`version must be ${PROOF_INTEGRATION_VERSION}; received ${JSON.stringify(file.version ?? null)}`);
|
|
78737
|
-
if (!Array.isArray(file.integrations) || file.integrations.length === 0) {
|
|
78738
|
-
errors.push("integrations must be a non-empty array");
|
|
78739
|
-
return errors;
|
|
78740
|
-
}
|
|
78741
|
-
const seen = new Set;
|
|
78742
|
-
file.integrations.forEach((entry, index) => {
|
|
78743
|
-
const row = record5(entry);
|
|
78744
|
-
const label = `integrations[${index}]`;
|
|
78745
|
-
if (!row) {
|
|
78746
|
-
errors.push(`${label} must be an object`);
|
|
78747
|
-
return;
|
|
78748
|
-
}
|
|
78749
|
-
if (!nonEmpty(row.id))
|
|
78750
|
-
errors.push(`${label}.id must be a non-empty string`);
|
|
78751
|
-
else {
|
|
78752
|
-
if (seen.has(String(row.id)))
|
|
78753
|
-
errors.push(`${label}.id duplicates '${String(row.id)}'`);
|
|
78754
|
-
seen.add(String(row.id));
|
|
78755
|
-
}
|
|
78756
|
-
if (!nonEmpty(row.producer))
|
|
78757
|
-
errors.push(`${label}.producer must be one of: ${PRODUCER_KINDS.join(", ")} (or a custom producer id)`);
|
|
78758
|
-
if (!Array.isArray(row.command) || row.command.length === 0 || !row.command.every((argument) => nonEmpty(argument)))
|
|
78759
|
-
errors.push(`${label}.command must be a non-empty argv array`);
|
|
78760
|
-
if (nonEmpty(row.producer) && (row.producer === "junit" || row.producer === "tap") && !nonEmpty(row.artifact))
|
|
78761
|
-
errors.push(`${label}.artifact is required for producer '${String(row.producer)}' (path of the native report to convert)`);
|
|
78762
|
-
if (row.targets !== undefined) {
|
|
78763
|
-
if (!Array.isArray(row.targets) || row.targets.length === 0 || !row.targets.every((target) => nonEmpty(target)))
|
|
78764
|
-
errors.push(`${label}.targets must be a non-empty array of target names`);
|
|
78765
|
-
}
|
|
78766
|
-
if (row.options !== undefined && !record5(row.options))
|
|
78767
|
-
errors.push(`${label}.options must be an object when present`);
|
|
78768
|
-
if (row.description !== undefined && !nonEmpty(row.description))
|
|
78769
|
-
errors.push(`${label}.description must be a non-empty string when present`);
|
|
78770
|
-
});
|
|
78771
|
-
return errors;
|
|
78772
|
-
}
|
|
78773
|
-
function loadProofIntegrations(workspaceRoot) {
|
|
78774
|
-
const filePath = integrationsPath(workspaceRoot);
|
|
78775
|
-
if (!existsSync41(filePath)) {
|
|
78776
|
-
return {
|
|
78777
|
-
available: false,
|
|
78778
|
-
error: `No proof integration configuration at ${PROOF_INTEGRATIONS_PATH}. Run bootstrap for this repository to configure proof producers.`
|
|
78779
|
-
};
|
|
78780
|
-
}
|
|
78781
|
-
let parsed;
|
|
78782
|
-
try {
|
|
78783
|
-
parsed = JSON.parse(readFileSync48(filePath, "utf8"));
|
|
78784
|
-
} catch (error) {
|
|
78785
|
-
return {
|
|
78786
|
-
available: false,
|
|
78787
|
-
error: `${PROOF_INTEGRATIONS_PATH} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`
|
|
78788
|
-
};
|
|
78789
|
-
}
|
|
78790
|
-
const errors = proofIntegrationErrors(parsed);
|
|
78791
|
-
if (errors.length > 0)
|
|
78792
|
-
return {
|
|
78793
|
-
available: false,
|
|
78794
|
-
error: `Invalid ${PROOF_INTEGRATIONS_PATH}: ${errors.join("; ")}`
|
|
78795
|
-
};
|
|
78796
|
-
return { available: true, integrations: parsed };
|
|
78797
|
-
}
|
|
78798
|
-
function resolveIntegration(integrations, id) {
|
|
78799
|
-
return integrations.integrations.find((entry) => entry.id === id) ?? null;
|
|
78800
|
-
}
|
|
78801
|
-
function toExecution(integration) {
|
|
78802
|
-
return {
|
|
78803
|
-
id: integration.id,
|
|
78804
|
-
producer: integration.producer,
|
|
78805
|
-
...integration.producer_version !== undefined ? { producer_version: integration.producer_version } : {},
|
|
78806
|
-
command: integration.command,
|
|
78807
|
-
...integration.artifact !== undefined ? { artifact: integration.artifact } : {},
|
|
78808
|
-
...integration.targets !== undefined ? { targets: integration.targets } : {},
|
|
78809
|
-
...integration.options !== undefined ? { options: integration.options } : {}
|
|
78810
|
-
};
|
|
78811
|
-
}
|
|
78812
|
-
function record5(value) {
|
|
78813
|
-
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
78814
|
-
}
|
|
78815
|
-
function nonEmpty(value) {
|
|
78816
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
78817
|
-
}
|
|
78818
|
-
var PROOF_INTEGRATIONS_PATH = ".kb/proof/integrations.json", PRODUCER_KINDS;
|
|
78819
|
-
var init_integrations = __esm(() => {
|
|
78820
|
-
init_proof_protocol();
|
|
78821
|
-
PRODUCER_KINDS = [
|
|
78822
|
-
"command",
|
|
78823
|
-
"playwright",
|
|
78824
|
-
"junit",
|
|
78825
|
-
"tap"
|
|
78826
|
-
];
|
|
78827
|
-
});
|
|
78828
|
-
|
|
78829
79249
|
// ../cli/dist/operations/mutation/entity-projection.js
|
|
78830
79250
|
function projectEntityProperties(entity) {
|
|
78831
79251
|
const relationshipKeys = new Set(RELATIONSHIP_TYPES2);
|
|
@@ -79324,11 +79744,11 @@ function validateInput(input) {
|
|
|
79324
79744
|
}
|
|
79325
79745
|
return endpoint;
|
|
79326
79746
|
}
|
|
79327
|
-
function
|
|
79747
|
+
function isRecord25(value) {
|
|
79328
79748
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
79329
79749
|
}
|
|
79330
79750
|
function decodeRows(payload) {
|
|
79331
|
-
if (!
|
|
79751
|
+
if (!isRecord25(payload) || !isRecord25(payload.results)) {
|
|
79332
79752
|
throw new Error("SPARQL endpoint returned an invalid result document");
|
|
79333
79753
|
}
|
|
79334
79754
|
const bindings = payload.results.bindings;
|
|
@@ -79336,12 +79756,12 @@ function decodeRows(payload) {
|
|
|
79336
79756
|
throw new Error("SPARQL endpoint returned an invalid bindings array");
|
|
79337
79757
|
}
|
|
79338
79758
|
const rows = bindings.map((binding) => {
|
|
79339
|
-
if (!
|
|
79759
|
+
if (!isRecord25(binding)) {
|
|
79340
79760
|
throw new Error("SPARQL endpoint returned an invalid binding");
|
|
79341
79761
|
}
|
|
79342
79762
|
const row = {};
|
|
79343
79763
|
for (const [variable, term] of Object.entries(binding)) {
|
|
79344
|
-
if (!
|
|
79764
|
+
if (!isRecord25(term) || typeof term.value !== "string") {
|
|
79345
79765
|
throw new Error(`SPARQL endpoint returned an invalid ${variable} term`);
|
|
79346
79766
|
}
|
|
79347
79767
|
row[variable] = term.value;
|
|
@@ -79625,10 +80045,10 @@ init_generate();
|
|
|
79625
80045
|
init_presentation();
|
|
79626
80046
|
init_ir();
|
|
79627
80047
|
// src/skill-operations.ts
|
|
79628
|
-
import { createHash as
|
|
80048
|
+
import { createHash as createHash42 } from "node:crypto";
|
|
79629
80049
|
|
|
79630
80050
|
// src/skill-system/loader.ts
|
|
79631
|
-
import { existsSync as
|
|
80051
|
+
import { existsSync as existsSync45, readFileSync as readFileSync51, readdirSync as readdirSync14, realpathSync as realpathSync10 } from "node:fs";
|
|
79632
80052
|
import { dirname as dirname22, join as join34, resolve as resolve29 } from "node:path";
|
|
79633
80053
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
79634
80054
|
|
|
@@ -79675,7 +80095,7 @@ class SkillOversizeError2 extends Error {
|
|
|
79675
80095
|
}
|
|
79676
80096
|
|
|
79677
80097
|
// src/skill-system/paths.ts
|
|
79678
|
-
import { existsSync as
|
|
80098
|
+
import { existsSync as existsSync43, statSync as statSync13 } from "node:fs";
|
|
79679
80099
|
import { isAbsolute as isAbsolute19, join as join33, normalize as normalize3, relative as relative20, resolve as resolve27 } from "node:path";
|
|
79680
80100
|
var SKILL_FILE_NAME2 = "SKILL.md";
|
|
79681
80101
|
function normalizeResourcePath2(pathLike) {
|
|
@@ -79691,7 +80111,7 @@ function isWithinRoot3(rootDir, candidatePath) {
|
|
|
79691
80111
|
}
|
|
79692
80112
|
function resolveSkillFilePath2(pathLike) {
|
|
79693
80113
|
const resolved = resolve27(pathLike);
|
|
79694
|
-
if (
|
|
80114
|
+
if (existsSync43(resolved) && statSync13(resolved).isDirectory())
|
|
79695
80115
|
return join33(resolved, SKILL_FILE_NAME2);
|
|
79696
80116
|
return resolved.endsWith(SKILL_FILE_NAME2) ? resolved : join33(resolved, SKILL_FILE_NAME2);
|
|
79697
80117
|
}
|
|
@@ -79816,7 +80236,7 @@ function isStringArray2(value) {
|
|
|
79816
80236
|
var moduleDir = dirname22(fileURLToPath5(import.meta.url));
|
|
79817
80237
|
var overrideSkillsDir;
|
|
79818
80238
|
function defaultBundledSkillsDir2() {
|
|
79819
|
-
return
|
|
80239
|
+
return existsSync45(resolve29(moduleDir, "skills")) ? resolve29(moduleDir, "skills") : resolve29(moduleDir, "../skills");
|
|
79820
80240
|
}
|
|
79821
80241
|
function setBundledSkillsDir2(dir) {
|
|
79822
80242
|
overrideSkillsDir = dir;
|
|
@@ -79846,17 +80266,17 @@ function readBundledSkillResourceFrom2(skillsDir, id, resourcePath) {
|
|
|
79846
80266
|
return readBundle2(loadBundledSkillFrom2(skillsDir, id), id, resourcePath);
|
|
79847
80267
|
}
|
|
79848
80268
|
function listFrom2(dir) {
|
|
79849
|
-
if (!
|
|
80269
|
+
if (!existsSync45(dir))
|
|
79850
80270
|
return [];
|
|
79851
|
-
return
|
|
80271
|
+
return readdirSync14(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join34(dir, entry.name)).filter((root) => existsSync45(join34(root, SKILL_FILE_NAME2))).map((root) => parseSkillBundle2(root).manifest).sort((a, b) => a.id.localeCompare(b.id));
|
|
79852
80272
|
}
|
|
79853
80273
|
function findRoot2(dir, id) {
|
|
79854
80274
|
return listRoots2(dir).find((root) => parseSkillBundle2(root).manifest.id === id);
|
|
79855
80275
|
}
|
|
79856
80276
|
function listRoots2(dir) {
|
|
79857
|
-
if (!
|
|
80277
|
+
if (!existsSync45(dir))
|
|
79858
80278
|
return [];
|
|
79859
|
-
return
|
|
80279
|
+
return readdirSync14(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join34(dir, entry.name)).filter((root) => existsSync45(join34(root, SKILL_FILE_NAME2)));
|
|
79860
80280
|
}
|
|
79861
80281
|
function readBundle2(bundle, id, resourcePath) {
|
|
79862
80282
|
const resource = normalizeResourcePath2(resourcePath);
|
|
@@ -79874,7 +80294,7 @@ function readBundle2(bundle, id, resourcePath) {
|
|
|
79874
80294
|
throw new SkillResourceNotFoundError2(id, resourcePath);
|
|
79875
80295
|
}
|
|
79876
80296
|
assertMaxBytes2(candidate, RESOURCE_MAX_BYTES2);
|
|
79877
|
-
return
|
|
80297
|
+
return readFileSync51(candidate, "utf8");
|
|
79878
80298
|
}
|
|
79879
80299
|
// src/skill-operations.ts
|
|
79880
80300
|
function assertNonEmptyString2(value, field) {
|
|
@@ -79897,7 +80317,7 @@ async function executeSkillsLoad2(input, _context) {
|
|
|
79897
80317
|
assertNonEmptyString2(id, "id");
|
|
79898
80318
|
const bundle = loadBundledSkill2(id);
|
|
79899
80319
|
const resources = bundle.manifest.resources ?? [];
|
|
79900
|
-
const contentHash =
|
|
80320
|
+
const contentHash = createHash42("sha256").update(bundle.body, "utf8").digest("hex");
|
|
79901
80321
|
const resourceList = resources.length === 0 ? "none" : resources.join(", ");
|
|
79902
80322
|
return {
|
|
79903
80323
|
content: [
|
|
@@ -79997,6 +80417,7 @@ init_branch_store_locator();
|
|
|
79997
80417
|
init_detached_snapshot();
|
|
79998
80418
|
|
|
79999
80419
|
// src/index.ts
|
|
80420
|
+
init_result_envelope();
|
|
80000
80421
|
init_engine();
|
|
80001
80422
|
|
|
80002
80423
|
// ../cli/dist/public/prolog/index.js
|
|
@@ -80031,7 +80452,7 @@ init_symbols_coordinator2();
|
|
|
80031
80452
|
// ../cli/dist/env/bootstrap.js
|
|
80032
80453
|
import fs13 from "node:fs";
|
|
80033
80454
|
import os2 from "node:os";
|
|
80034
|
-
import
|
|
80455
|
+
import path83 from "node:path";
|
|
80035
80456
|
var WORKSPACE_ENV_KEYS = [
|
|
80036
80457
|
"KIBI_WORKSPACE",
|
|
80037
80458
|
"KIBI_PROJECT_ROOT",
|
|
@@ -80057,13 +80478,13 @@ function readFirstEnv(env, keys) {
|
|
|
80057
80478
|
return null;
|
|
80058
80479
|
}
|
|
80059
80480
|
function nextAncestorDirectory2(current) {
|
|
80060
|
-
const parent =
|
|
80481
|
+
const parent = path83.dirname(current);
|
|
80061
80482
|
return parent === current ? undefined : parent;
|
|
80062
80483
|
}
|
|
80063
80484
|
function findUpwards(startDir, marker) {
|
|
80064
|
-
let current =
|
|
80485
|
+
let current = path83.resolve(startDir);
|
|
80065
80486
|
while (current !== undefined) {
|
|
80066
|
-
if (fs13.existsSync(
|
|
80487
|
+
if (fs13.existsSync(path83.join(current, marker))) {
|
|
80067
80488
|
return current;
|
|
80068
80489
|
}
|
|
80069
80490
|
current = nextAncestorDirectory2(current);
|
|
@@ -80073,24 +80494,24 @@ function findUpwards(startDir, marker) {
|
|
|
80073
80494
|
function resolveKibiWorkspaceRoot(startDir = process.cwd(), env = process.env) {
|
|
80074
80495
|
const envRoot = readFirstEnv(env, WORKSPACE_ENV_KEYS);
|
|
80075
80496
|
if (envRoot)
|
|
80076
|
-
return
|
|
80497
|
+
return path83.resolve(envRoot);
|
|
80077
80498
|
const kbRoot = findUpwards(startDir, ".kb");
|
|
80078
80499
|
if (kbRoot)
|
|
80079
80500
|
return kbRoot;
|
|
80080
80501
|
const gitRoot = findUpwards(startDir, ".git");
|
|
80081
80502
|
if (gitRoot)
|
|
80082
80503
|
return gitRoot;
|
|
80083
|
-
return
|
|
80504
|
+
return path83.resolve(startDir);
|
|
80084
80505
|
}
|
|
80085
80506
|
function resolveEnvFilePath(envFileName, workspaceRoot) {
|
|
80086
|
-
if (
|
|
80507
|
+
if (path83.isAbsolute(envFileName))
|
|
80087
80508
|
return envFileName;
|
|
80088
|
-
return
|
|
80509
|
+
return path83.resolve(workspaceRoot, envFileName);
|
|
80089
80510
|
}
|
|
80090
80511
|
function resolveKibiUserEnvPath(options2 = {}) {
|
|
80091
80512
|
const env = options2.env ?? process.env;
|
|
80092
|
-
const xdg = options2.xdgConfigHome?.trim() || env.XDG_CONFIG_HOME?.trim() ||
|
|
80093
|
-
return
|
|
80513
|
+
const xdg = options2.xdgConfigHome?.trim() || env.XDG_CONFIG_HOME?.trim() || path83.join(options2.homedir ?? os2.homedir(), ".config");
|
|
80514
|
+
return path83.join(xdg, "kibi", "env");
|
|
80094
80515
|
}
|
|
80095
80516
|
function resolveKibiProjectEnvPath(workspaceRoot, env = process.env) {
|
|
80096
80517
|
const override = env.KIBI_ENV_FILE?.trim();
|