kibi-cli 2.21.0 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-operation-metadata.d.ts +1 -1
- package/dist/cli-operation-metadata.js +1 -1
- package/dist/cli-register-foundation.d.ts.map +1 -1
- package/dist/cli-register-foundation.js +1 -0
- package/dist/commands/check.d.ts +0 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +47 -111
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +107 -5
- package/dist/commands/init-helpers.d.ts +14 -1
- package/dist/commands/init-helpers.d.ts.map +1 -1
- package/dist/commands/init-helpers.js +49 -10
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +27 -4
- package/dist/commands/legacy-storage-migration.d.ts +46 -1
- package/dist/commands/legacy-storage-migration.d.ts.map +1 -1
- package/dist/commands/legacy-storage-migration.js +244 -9
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +150 -166
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +9 -0
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +4 -0
- package/dist/decision-firmness.d.ts +39 -0
- package/dist/decision-firmness.d.ts.map +1 -0
- package/dist/decision-firmness.js +115 -0
- package/dist/extractors/markdown.d.ts +2 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +14 -0
- package/dist/extractors/symbols-coordinator.js +1 -0
- package/dist/intent-search.d.ts.map +1 -1
- package/dist/intent-search.js +28 -6
- package/dist/operations/migration/inventory-rederive.d.ts +40 -1
- package/dist/operations/migration/inventory-rederive.d.ts.map +1 -1
- package/dist/operations/migration/inventory-rederive.js +99 -8
- package/dist/operations/migration/requirement-status.d.ts +25 -0
- package/dist/operations/migration/requirement-status.d.ts.map +1 -0
- package/dist/operations/migration/requirement-status.js +105 -0
- package/dist/operations/migration/schema6.d.ts +27 -0
- package/dist/operations/migration/schema6.d.ts.map +1 -1
- package/dist/operations/migration/schema6.js +308 -7
- package/dist/operations/migration/supersedes-reason.d.ts +26 -0
- package/dist/operations/migration/supersedes-reason.d.ts.map +1 -0
- package/dist/operations/migration/supersedes-reason.js +69 -0
- package/dist/operations/migration/symbol-legacy-links.d.ts +51 -0
- package/dist/operations/migration/symbol-legacy-links.d.ts.map +1 -0
- package/dist/operations/migration/symbol-legacy-links.js +319 -0
- package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-applyplan.js +10 -2
- package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-loader.js +11 -0
- package/dist/operations/modeling/predicate-types.d.ts +32 -1
- package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
- package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
- package/dist/operations/modeling/suggest-predicates.js +175 -35
- package/dist/operations/mutation/context-warning.d.ts +12 -2
- package/dist/operations/mutation/context-warning.d.ts.map +1 -1
- package/dist/operations/mutation/context-warning.js +6 -6
- package/dist/operations/mutation/delete.d.ts +5 -1
- package/dist/operations/mutation/delete.d.ts.map +1 -1
- package/dist/operations/mutation/delete.js +223 -17
- package/dist/operations/mutation/serialization.d.ts.map +1 -1
- package/dist/operations/mutation/serialization.js +1 -0
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +130 -35
- package/dist/operations/mutation/types.d.ts +39 -1
- package/dist/operations/mutation/types.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.d.ts +17 -2
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +82 -13
- package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
- package/dist/operations/mutation/validate-upsert.js +40 -8
- package/dist/operations/planning/apply-plan.d.ts +6 -1
- package/dist/operations/planning/apply-plan.d.ts.map +1 -1
- package/dist/operations/planning/apply-plan.js +26 -5
- package/dist/public/impact/diagnostics.d.ts.map +1 -1
- package/dist/public/impact/diagnostics.js +24 -14
- package/dist/public/operations/catalog.d.ts +14 -5
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +6 -0
- package/dist/public/operations/contracts.d.ts.map +1 -1
- package/dist/public/operations/contracts.js +35 -2
- package/dist/public/operations/decision-firmness.d.ts +34 -0
- package/dist/public/operations/decision-firmness.d.ts.map +1 -0
- package/dist/public/operations/decision-firmness.js +216 -0
- package/dist/public/operations/discovery-executors.d.ts +2 -0
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +25 -4
- package/dist/public/operations/migration-plan.d.ts +2 -0
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +101 -16
- package/dist/public/operations/result-envelope.d.ts.map +1 -1
- package/dist/public/operations/result-envelope.js +27 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
- package/dist/public/operations/specs/check-rules.generated.js +6 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts +5 -0
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +5 -0
- package/dist/public/operations/specs/mutation.d.ts +6 -2
- package/dist/public/operations/specs/mutation.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation.js +6 -2
- package/dist/public/operations/specs/planning.d.ts +2 -2
- package/dist/public/operations/specs/planning.js +2 -2
- package/dist/public/operations/specs/upsert.d.ts +5 -0
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/operations/symbol-granularity-check.d.ts +18 -0
- package/dist/public/operations/symbol-granularity-check.d.ts.map +1 -0
- package/dist/public/operations/symbol-granularity-check.js +175 -0
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +11 -0
- package/dist/public/skills/kibi-traceability/SKILL.md +6 -4
- package/dist/public/skills/kibi-usage/SKILL.md +50 -10
- package/dist/public/skills/kibi-usage/resources/source-authoring.md +4 -2
- package/dist/public/symbol-granularity.d.ts +17 -0
- package/dist/public/symbol-granularity.d.ts.map +1 -1
- package/dist/public/symbol-granularity.js +21 -0
- package/dist/relationships/shards.d.ts +10 -0
- package/dist/relationships/shards.d.ts.map +1 -1
- package/dist/relationships/shards.js +27 -11
- package/dist/schemas/entity.schema.json +28 -0
- package/dist/search-answer.d.ts +31 -2
- package/dist/search-answer.d.ts.map +1 -1
- package/dist/search-answer.js +115 -17
- package/dist/traceability/evidence-model.d.ts +7 -3
- package/dist/traceability/evidence-model.d.ts.map +1 -1
- package/dist/traceability/staged-symbols-manifest.js +6 -5
- package/dist/traceability/validate.d.ts +14 -1
- package/dist/traceability/validate.d.ts.map +1 -1
- package/dist/traceability/validate.js +41 -0
- package/dist/types/entities.d.ts +4 -0
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/utils/kb-manifest.d.ts +6 -0
- package/dist/utils/kb-manifest.d.ts.map +1 -1
- package/dist/utils/kb-manifest.js +6 -0
- package/dist/utils/rule-registry.generated.d.ts +26 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +31 -0
- package/dist/utils/schema-version.d.ts +1 -1
- package/dist/utils/schema-version.d.ts.map +1 -1
- package/dist/utils/schema-version.js +3 -1
- package/package.json +3 -3
- package/schema/entities.pl +6 -0
- package/src/public/impact/diagnostics.ts +29 -17
- package/src/public/operations/check-executor.ts +13 -0
- package/src/public/operations/contracts.ts +39 -2
- package/src/public/operations/decision-firmness.ts +280 -0
- package/src/public/operations/discovery-executors.ts +29 -4
- package/src/public/operations/migration-plan.ts +100 -19
- package/src/public/operations/result-envelope.ts +34 -1
- package/src/public/operations/specs/check-rules.generated.ts +6 -1
- package/src/public/operations/specs/mutation-schemas.ts +6 -0
- package/src/public/operations/specs/mutation.ts +7 -2
- package/src/public/operations/specs/planning.ts +2 -2
- package/src/public/operations/symbol-granularity-check.ts +233 -0
- package/src/public/schemas/entity.ts +12 -0
- package/src/public/skills/kibi-traceability/SKILL.md +6 -4
- package/src/public/skills/kibi-usage/SKILL.md +50 -10
- package/src/public/skills/kibi-usage/resources/source-authoring.md +4 -2
- package/src/public/symbol-granularity.ts +37 -0
- package/src/schemas/entity.schema.json +28 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
3
|
+
Copyright (C) 2026 Piotr Franczyk
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Affero General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Decision firmness: how firmly a requirement or ADR was decided, which tells
|
|
20
|
+
* a later agent whether it may supersede the decision on evidence or must ask
|
|
21
|
+
* a human first. This module is the one place that knows the values, the
|
|
22
|
+
* default and what a supersede must explain, so extraction, checks, search,
|
|
23
|
+
* query and migration agree.
|
|
24
|
+
*/
|
|
25
|
+
import { parseBodySections } from "./entity-body-context.js";
|
|
26
|
+
/** Firmness values, firmest first. */
|
|
27
|
+
// implements REQ-kb-decision-firmness
|
|
28
|
+
export const FIRMNESS_VALUES = ["firm", "default", "exploratory"];
|
|
29
|
+
/** The firmness of a decision that does not state one. */
|
|
30
|
+
// implements REQ-kb-decision-firmness
|
|
31
|
+
export const DEFAULT_FIRMNESS = "default";
|
|
32
|
+
/** Entity types that carry firmness. */
|
|
33
|
+
// implements REQ-kb-decision-firmness
|
|
34
|
+
export const FIRMNESS_TYPES = ["req", "adr"];
|
|
35
|
+
/** A supersede must explain itself under a heading starting with this. */
|
|
36
|
+
// implements REQ-kb-decision-firmness
|
|
37
|
+
export const WHY_THIS_CHANGED_HEADING = "Why this changed";
|
|
38
|
+
/** The explanation needs at least this many words of prose. */
|
|
39
|
+
// implements REQ-kb-decision-firmness
|
|
40
|
+
export const MIN_WHY_CHANGED_WORDS = 12;
|
|
41
|
+
const WHY_THIS_CHANGED = /^why\s+this\s+changed\b/i;
|
|
42
|
+
/**
|
|
43
|
+
* How the manifest records one acknowledged supersede edge. Edges, not ids,
|
|
44
|
+
* are acknowledged, so a supersede added later to the same entity still has
|
|
45
|
+
* to explain itself.
|
|
46
|
+
*/
|
|
47
|
+
// implements REQ-kb-decision-firmness
|
|
48
|
+
export function supersedeAcknowledgement(from, to) {
|
|
49
|
+
return `${from} -> ${to}`;
|
|
50
|
+
}
|
|
51
|
+
// implements REQ-kb-decision-firmness
|
|
52
|
+
export function isFirmness(value) {
|
|
53
|
+
return (typeof value === "string" &&
|
|
54
|
+
FIRMNESS_VALUES.includes(value));
|
|
55
|
+
}
|
|
56
|
+
// implements REQ-kb-decision-firmness
|
|
57
|
+
export function carriesFirmness(type) {
|
|
58
|
+
return (typeof type === "string" &&
|
|
59
|
+
FIRMNESS_TYPES.includes(type));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The firmness a decision is read with: the authored value, else `default`.
|
|
63
|
+
* Undefined for types that carry no firmness.
|
|
64
|
+
*/
|
|
65
|
+
// implements REQ-kb-decision-firmness
|
|
66
|
+
export function effectiveFirmness(type, value) {
|
|
67
|
+
if (!carriesFirmness(type))
|
|
68
|
+
return undefined;
|
|
69
|
+
return isFirmness(value) ? value : DEFAULT_FIRMNESS;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The reference that makes a firm decision traceable to a human's words:
|
|
73
|
+
* `origin.ref`, or `approval_ref` on a requirement.
|
|
74
|
+
*/
|
|
75
|
+
// implements REQ-kb-decision-firmness
|
|
76
|
+
export function firmnessRef(entity) {
|
|
77
|
+
const origin = entity.origin;
|
|
78
|
+
if (origin !== null && typeof origin === "object") {
|
|
79
|
+
const ref = origin.ref;
|
|
80
|
+
if (typeof ref === "string" && ref.trim() !== "")
|
|
81
|
+
return ref.trim();
|
|
82
|
+
}
|
|
83
|
+
if (entity.type === "req" &&
|
|
84
|
+
typeof entity.approval_ref === "string" &&
|
|
85
|
+
entity.approval_ref.trim() !== "") {
|
|
86
|
+
return entity.approval_ref.trim();
|
|
87
|
+
}
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
function wordCount(text) {
|
|
91
|
+
return text.split(/\s+/).filter((word) => /[\p{L}\p{N}]/u.test(word)).length;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Words of prose under the body's "Why this changed" heading (nested
|
|
95
|
+
* headings included), or 0 when the body has no such section.
|
|
96
|
+
*/
|
|
97
|
+
// implements REQ-kb-decision-firmness
|
|
98
|
+
export function whyThisChangedWords(body) {
|
|
99
|
+
const sections = parseBodySections(body);
|
|
100
|
+
let level = null;
|
|
101
|
+
let words = 0;
|
|
102
|
+
for (const section of sections) {
|
|
103
|
+
if (level !== null && section.level > 0 && section.level <= level) {
|
|
104
|
+
level = null;
|
|
105
|
+
}
|
|
106
|
+
if (level === null &&
|
|
107
|
+
section.level > 0 &&
|
|
108
|
+
WHY_THIS_CHANGED.test(section.heading.replace(/^[*_`\s]+/, ""))) {
|
|
109
|
+
level = section.level;
|
|
110
|
+
}
|
|
111
|
+
if (level !== null)
|
|
112
|
+
words += wordCount(section.text);
|
|
113
|
+
}
|
|
114
|
+
return words;
|
|
115
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Firmness } from "../decision-firmness.js";
|
|
1
2
|
import { type EntityOrigin } from "../public/entity-origin.js";
|
|
2
3
|
import { type ProofBinding, type ProofContract } from "../public/proof-protocol.js";
|
|
3
4
|
import { type ProofReceipt } from "../public/proof-receipt.js";
|
|
@@ -15,6 +16,7 @@ export interface ExtractedEntity {
|
|
|
15
16
|
severity?: string;
|
|
16
17
|
text_ref?: string;
|
|
17
18
|
origin?: EntityOrigin;
|
|
19
|
+
firmness?: Firmness;
|
|
18
20
|
semantic_text?: string;
|
|
19
21
|
logic_claims?: string[];
|
|
20
22
|
semantic_clauses?: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,7 @@ import { createHash } from "node:crypto";
|
|
|
19
19
|
import { readFileSync } from "node:fs";
|
|
20
20
|
import Ajv from "ajv";
|
|
21
21
|
import { load as yamlLoad } from "js-yaml";
|
|
22
|
+
import { FIRMNESS_VALUES, carriesFirmness, isFirmness, } from "../decision-firmness.js";
|
|
22
23
|
import { withoutContextSections } from "../entity-body-context.js";
|
|
23
24
|
import { deriveFactClaimKey, semanticClaimKey, } from "../operations/semantic-advisor/clauses.js";
|
|
24
25
|
import { normalizeEntityOrigin, } from "../public/entity-origin.js";
|
|
@@ -511,6 +512,19 @@ function extractFromMarkdownContent(content, filePath) {
|
|
|
511
512
|
}
|
|
512
513
|
entity.rationale = data.rationale;
|
|
513
514
|
}
|
|
515
|
+
// implements REQ-kb-decision-firmness
|
|
516
|
+
// How firmly a requirement or ADR was decided; absent reads as default.
|
|
517
|
+
if (data.firmness !== undefined) {
|
|
518
|
+
if (!carriesFirmness(type) || !isFirmness(data.firmness)) {
|
|
519
|
+
throw new FrontmatterError(carriesFirmness(type)
|
|
520
|
+
? `Invalid firmness; expected one of ${FIRMNESS_VALUES.join(", ")}`
|
|
521
|
+
: "firmness is only allowed on type: req or adr", filePath, {
|
|
522
|
+
classification: "Invalid Firmness",
|
|
523
|
+
hint: "Use firm only for a rule a human stated (with origin.ref to their words), default for a delegated or agent choice, exploratory for a flagged guess; remove the field from other entity types.",
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
entity.firmness = data.firmness;
|
|
527
|
+
}
|
|
514
528
|
if (type === "req" && Array.isArray(data.exempts_claims)) {
|
|
515
529
|
entity.exempts_claims = data.exempts_claims.filter((value) => typeof value === "string");
|
|
516
530
|
}
|
|
@@ -191,6 +191,7 @@ function withoutGeneratedCoordinates(entry) {
|
|
|
191
191
|
"sourceEndLine",
|
|
192
192
|
"sourceEndColumn",
|
|
193
193
|
"coordinatesGeneratedAt",
|
|
194
|
+
"coordinateRefreshFailure",
|
|
194
195
|
]);
|
|
195
196
|
return Object.fromEntries(Object.entries(entry).filter(([field]) => !generatedFields.has(field)));
|
|
196
197
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent-search.d.ts","sourceRoot":"","sources":["../src/intent-search.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,kBAAkB,EAIxB,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIvD,MAAM,MAAM,qBAAqB,GAC7B,QAAQ,GACR,SAAS,GACT,SAAS,GACT,aAAa,GACb,SAAS,CAAC;AAGd,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CACvC,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAC1D,CAAC;AAGF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACpD,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,eAAe,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAGH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAGH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC,CAAC;AAGH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,aAAa,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC5C,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;IACvC,kBAAkB,EAAE,OAAO,CAAC;CAC7B,CAAC,CAAC;AAGH,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG;IAC5C,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;CACzC,CAAC;AAGF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC,CAAC;AAGH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtC,QAAQ,EAAE,oBAAoB,CAAC;CAChC,CAAC,CAAC;AAEH,KAAK,SAAS,GAAG,QAAQ,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"intent-search.d.ts","sourceRoot":"","sources":["../src/intent-search.ts"],"names":[],"mappings":"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"}
|
package/dist/intent-search.js
CHANGED
|
@@ -153,6 +153,22 @@ function tokens(value) {
|
|
|
153
153
|
.split(" ")
|
|
154
154
|
.filter((token) => token.length > 0 && !STOP_WORDS.has(token))));
|
|
155
155
|
}
|
|
156
|
+
// Clause boundaries an agent writes when it packs several questions into one
|
|
157
|
+
// query: "user roles: how many can a user have, support role".
|
|
158
|
+
const CLAUSE_SEPARATOR = /[;:,!?\n]+|\.(?=\s|$)|\s[-\u2013\u2014]\s/;
|
|
159
|
+
const MIN_CLAUSE_TOKENS = 2;
|
|
160
|
+
/**
|
|
161
|
+
* The token sets of a compound query's clauses, or none for a single clause.
|
|
162
|
+
* A clause needs two signal tokens: one word alone matches too broadly to
|
|
163
|
+
* stand in for the question.
|
|
164
|
+
*/
|
|
165
|
+
function queryClauses(query) {
|
|
166
|
+
const clauses = query
|
|
167
|
+
.split(CLAUSE_SEPARATOR)
|
|
168
|
+
.map((clause) => tokens(clause))
|
|
169
|
+
.filter((clause) => clause.length >= MIN_CLAUSE_TOKENS);
|
|
170
|
+
return clauses.length > 1 ? clauses : [];
|
|
171
|
+
}
|
|
156
172
|
function stringValues(value) {
|
|
157
173
|
if (typeof value === "string")
|
|
158
174
|
return value.trim() ? [value] : [];
|
|
@@ -392,10 +408,11 @@ async function readBodies(entities, workspaceRoot, cache) {
|
|
|
392
408
|
export async function rankIntentEntities(entities, options, workspaceRoot, graphEdges = [], bodyCache = new Map()) {
|
|
393
409
|
const queryTokens = tokens(options.query);
|
|
394
410
|
const facets = facetValues(options.semanticFacets);
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
411
|
+
const facetTokens = facets.flatMap((facet) => tokens(facet.value));
|
|
412
|
+
const allTokens = Array.from(new Set([...queryTokens, ...facetTokens]));
|
|
413
|
+
// Each clause of a compound question is also scored on its own, so the
|
|
414
|
+
// words of one clause do not dilute a match on another.
|
|
415
|
+
const clauseTokenSets = queryClauses(options.query).map((clause) => Array.from(new Set([...clause, ...facetTokens])));
|
|
399
416
|
const bodies = await readBodies(entities, workspaceRoot, bodyCache);
|
|
400
417
|
const documentFrequency = buildDocumentFrequency(entities, bodies);
|
|
401
418
|
const supersededIds = new Set(graphEdges
|
|
@@ -428,8 +445,13 @@ export async function rankIntentEntities(entities, options, workspaceRoot, graph
|
|
|
428
445
|
// already capped; unbounded parallel paths only add noise to receipts.
|
|
429
446
|
const graphEvidence = (graphByEntity.get(entityId) ?? []).slice(0, 8);
|
|
430
447
|
const body = bodies.get(entity) ?? null;
|
|
431
|
-
|
|
432
|
-
|
|
448
|
+
let scored;
|
|
449
|
+
for (const signalTokens of [allTokens, ...clauseTokenSets]) {
|
|
450
|
+
const candidate = scoreEntity(entity, signalTokens, facets, sourceEvidence, graphEvidence, documentFrequency, entities.length, body, supersededIds.has(entityId), isProvenanceStub(entity));
|
|
451
|
+
if (scored === undefined || candidate.score > scored.score)
|
|
452
|
+
scored = candidate;
|
|
453
|
+
}
|
|
454
|
+
if (scored === undefined || scored.score < minScore)
|
|
433
455
|
continue;
|
|
434
456
|
const snippet = body === null
|
|
435
457
|
? undefined
|
|
@@ -51,6 +51,26 @@ export type InventoryRederivation = Readonly<{
|
|
|
51
51
|
contract: InventoryContract;
|
|
52
52
|
/** SHA-256 of the canonical re-derived contract; the apply step re-checks it. */
|
|
53
53
|
contractHash: string;
|
|
54
|
+
/**
|
|
55
|
+
* Grounding links (requires_*) whose target no longer grounds a modeled
|
|
56
|
+
* claim of the re-derived inventory. Empty for a safe re-derivation.
|
|
57
|
+
*/
|
|
58
|
+
orphanedGrounding: readonly OrphanedGroundingLink[];
|
|
59
|
+
/**
|
|
60
|
+
* True when an unsafe re-derivation passes ingestion once exactly the
|
|
61
|
+
* orphaned grounding links are removed from the requirement's front
|
|
62
|
+
* matter. A person approves that explicitly; it is never automatic.
|
|
63
|
+
*/
|
|
64
|
+
rederivableByDroppingGrounding: boolean;
|
|
65
|
+
}>;
|
|
66
|
+
/** A grounding link the re-derived inventory no longer supports. */
|
|
67
|
+
export type OrphanedGroundingLink = Readonly<{
|
|
68
|
+
type: string;
|
|
69
|
+
target: string;
|
|
70
|
+
/** The target fact's claim_key; null when it declares none. */
|
|
71
|
+
claimKey: string | null;
|
|
72
|
+
/** Declared in the requirement's front matter `links` (not a shard). */
|
|
73
|
+
inFrontMatter: boolean;
|
|
54
74
|
}>;
|
|
55
75
|
/**
|
|
56
76
|
* Every current requirement whose stored inventory contract no longer matches
|
|
@@ -58,7 +78,14 @@ export type InventoryRederivation = Readonly<{
|
|
|
58
78
|
* reports all of them instead of stopping at the first. `onlyId` limits the
|
|
59
79
|
* scan to one requirement.
|
|
60
80
|
*/
|
|
61
|
-
export declare function planInventoryRederivation(workspaceRoot: string, onlyId?: string
|
|
81
|
+
export declare function planInventoryRederivation(workspaceRoot: string, onlyId?: string, options?: Readonly<{
|
|
82
|
+
/**
|
|
83
|
+
* Plan as if the requirement had this status: a requirement whose status
|
|
84
|
+
* is outside the current vocabulary is not validated, so its drift only
|
|
85
|
+
* shows once the status is mapped.
|
|
86
|
+
*/
|
|
87
|
+
status?: string;
|
|
88
|
+
}>): InventoryRederivation[];
|
|
62
89
|
export type InventoryRederivationOutcome = Readonly<{
|
|
63
90
|
requirementId: string;
|
|
64
91
|
path: string;
|
|
@@ -72,6 +99,18 @@ export type InventoryRederivationOutcome = Readonly<{
|
|
|
72
99
|
* left unchanged, so repeated runs are no-ops.
|
|
73
100
|
*/
|
|
74
101
|
export declare function applyInventoryRederivation(workspaceRoot: string, requirementId: string, expectedContractHash?: string): InventoryRederivationOutcome;
|
|
102
|
+
/**
|
|
103
|
+
* Apply an unsafe re-derivation a person approved: write the re-derived
|
|
104
|
+
* contract and remove exactly `expectedDrops`, the orphaned grounding links
|
|
105
|
+
* the plan listed, from the requirement's front matter. The current plan must
|
|
106
|
+
* still produce the approved contract hash and the same orphaned links, and
|
|
107
|
+
* the rewritten requirement must pass ingestion before anything is written;
|
|
108
|
+
* the grounding facts themselves are left alone.
|
|
109
|
+
*/
|
|
110
|
+
export declare function applyInventoryRederivationDroppingGrounding(workspaceRoot: string, requirementId: string, expectedContractHash: string, expectedDrops: readonly Readonly<{
|
|
111
|
+
type: string;
|
|
112
|
+
target: string;
|
|
113
|
+
}>[]): InventoryRederivationOutcome;
|
|
75
114
|
/** Apply every safe re-derivation; unsafe ones are returned untouched. */
|
|
76
115
|
export declare function applySafeInventoryRederivations(workspaceRoot: string): {
|
|
77
116
|
rederived: InventoryRederivationOutcome[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inventory-rederive.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/inventory-rederive.ts"],"names":[],"mappings":"AA2EA,KAAK,cAAc,GAAG;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,gDAAgD;AAEhD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EACF,MAAM,GACN,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,aAAa,GACb,gBAAgB,GAChB,aAAa,GACb,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,KAAK,CAAC,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD,CAAC,CAAC;AAGH,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC,CAAC;AAEH,oEAAoE;AAEpE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,0BAA0B,EAAE,MAAM,CAAC;IACnC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC,CAAC,CAAC;AAGH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,4BAA4B,CAAC;IACtC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACzC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,iFAAiF;IACjF,YAAY,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"inventory-rederive.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/inventory-rederive.ts"],"names":[],"mappings":"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"}
|
|
@@ -138,7 +138,7 @@ function relationshipsFor(id, extracted, shards) {
|
|
|
138
138
|
for (const relationship of [...extracted, ...shards]) {
|
|
139
139
|
if (relationship.from !== id)
|
|
140
140
|
continue;
|
|
141
|
-
unique.set(
|
|
141
|
+
unique.set(relationshipKey(relationship), relationship);
|
|
142
142
|
}
|
|
143
143
|
return [...unique.values()];
|
|
144
144
|
}
|
|
@@ -267,20 +267,32 @@ function planOne(workspaceRoot, relativePath, entity, extracted, shards, facts)
|
|
|
267
267
|
for (const claimKey of modeledBecameContext) {
|
|
268
268
|
reasons.push(`modeled claim ${claimKey} is now classified as context (${inventory.find((entry) => entry.claim_key === claimKey)?.role ?? "context"}); its grounding cannot stay`);
|
|
269
269
|
}
|
|
270
|
+
const modeledKeys = inventory
|
|
271
|
+
.filter((entry) => entry.status === "modeled")
|
|
272
|
+
.map((entry) => entry.claim_key);
|
|
273
|
+
const declared = new Set(extracted
|
|
274
|
+
.filter((relationship) => relationship.from === entity.id)
|
|
275
|
+
.map(relationshipKey));
|
|
270
276
|
const groundingKeys = [];
|
|
277
|
+
const orphanedGrounding = [];
|
|
271
278
|
for (const relationship of relationships) {
|
|
272
279
|
if (!GROUNDING_RELATIONSHIPS.has(relationship.type))
|
|
273
280
|
continue;
|
|
274
281
|
const claimKey = facts.claimKey(relationship.to);
|
|
282
|
+
if (claimKey === undefined || !modeledKeys.includes(claimKey)) {
|
|
283
|
+
orphanedGrounding.push({
|
|
284
|
+
type: relationship.type,
|
|
285
|
+
target: relationship.to,
|
|
286
|
+
claimKey: claimKey ?? null,
|
|
287
|
+
inFrontMatter: declared.has(relationshipKey(relationship)),
|
|
288
|
+
});
|
|
289
|
+
}
|
|
275
290
|
if (claimKey === undefined) {
|
|
276
291
|
reasons.push(`grounding target ${relationship.to} (${relationship.type}) declares no claim_key`);
|
|
277
292
|
continue;
|
|
278
293
|
}
|
|
279
294
|
groundingKeys.push(claimKey);
|
|
280
295
|
}
|
|
281
|
-
const modeledKeys = inventory
|
|
282
|
-
.filter((entry) => entry.status === "modeled")
|
|
283
|
-
.map((entry) => entry.claim_key);
|
|
284
296
|
for (const claimKey of new Set(groundingKeys)) {
|
|
285
297
|
if (modeledKeys.includes(claimKey))
|
|
286
298
|
continue;
|
|
@@ -298,6 +310,14 @@ function planOne(workspaceRoot, relativePath, entity, extracted, shards, facts)
|
|
|
298
310
|
for (const error of after.errors) {
|
|
299
311
|
reasons.push(`re-derived inventory would still fail ingestion: ${error}`);
|
|
300
312
|
}
|
|
313
|
+
const orphaned = new Set(orphanedGrounding.map((link) => relationshipKey({ type: link.type, from: entity.id, to: link.target })));
|
|
314
|
+
const rederivableByDroppingGrounding = reasons.length > 0 &&
|
|
315
|
+
orphanedGrounding.length > 0 &&
|
|
316
|
+
// A target without claim_key may ground something else (a property
|
|
317
|
+
// value, for example); only links to a claim that is no longer modeled
|
|
318
|
+
// are dropped, and only from the requirement's own front matter.
|
|
319
|
+
orphanedGrounding.every((link) => link.inFrontMatter && link.claimKey !== null) &&
|
|
320
|
+
validateSemanticInventoryBoundary(nextPayload, relationships.filter((relationship) => !orphaned.has(relationshipKey(relationship))), analyzeSemanticAdvisorInput({ payload: nextPayload }).receipt).errors.length === 0;
|
|
301
321
|
return {
|
|
302
322
|
requirementId: entity.id,
|
|
303
323
|
path: relativePath,
|
|
@@ -310,8 +330,13 @@ function planOne(workspaceRoot, relativePath, entity, extracted, shards, facts)
|
|
|
310
330
|
contractHash: createHash("sha256")
|
|
311
331
|
.update(canonicalJson(contract))
|
|
312
332
|
.digest("hex"),
|
|
333
|
+
orphanedGrounding,
|
|
334
|
+
rederivableByDroppingGrounding,
|
|
313
335
|
};
|
|
314
336
|
}
|
|
337
|
+
function relationshipKey(relationship) {
|
|
338
|
+
return `${relationship.type}\u0000${relationship.from}\u0000${relationship.to}`;
|
|
339
|
+
}
|
|
315
340
|
function readShardRelationships(workspaceRoot) {
|
|
316
341
|
try {
|
|
317
342
|
return readAllShards(path.join(workspaceRoot, ".kb")).map(({ type, from, to }) => ({ type, from, to }));
|
|
@@ -328,7 +353,7 @@ function readShardRelationships(workspaceRoot) {
|
|
|
328
353
|
* scan to one requirement.
|
|
329
354
|
*/
|
|
330
355
|
// implements REQ-kibi-proposition-complete-ingestion, REQ-cli-schema-migration
|
|
331
|
-
export function planInventoryRederivation(workspaceRoot, onlyId) {
|
|
356
|
+
export function planInventoryRederivation(workspaceRoot, onlyId, options = {}) {
|
|
332
357
|
const shards = readShardRelationships(workspaceRoot);
|
|
333
358
|
const facts = new FactClaimIndex(workspaceRoot);
|
|
334
359
|
const plans = [];
|
|
@@ -347,7 +372,9 @@ export function planInventoryRederivation(workspaceRoot, onlyId) {
|
|
|
347
372
|
}
|
|
348
373
|
if (onlyId !== undefined && result.entity.id !== onlyId)
|
|
349
374
|
continue;
|
|
350
|
-
const plan = planOne(workspaceRoot, file.relativePath,
|
|
375
|
+
const plan = planOne(workspaceRoot, file.relativePath, options.status === undefined
|
|
376
|
+
? result.entity
|
|
377
|
+
: { ...result.entity, status: options.status }, result.relationships, shards, facts);
|
|
351
378
|
if (plan !== null)
|
|
352
379
|
plans.push(plan);
|
|
353
380
|
}
|
|
@@ -357,7 +384,7 @@ export function planInventoryRederivation(workspaceRoot, onlyId) {
|
|
|
357
384
|
* Rewrite the inventory contract keys of one requirement's frontmatter and
|
|
358
385
|
* confirm every other frontmatter field reads back unchanged.
|
|
359
386
|
*/
|
|
360
|
-
function rewriteContract(content, contract) {
|
|
387
|
+
function rewriteContract(content, contract, dropLinks = []) {
|
|
361
388
|
const slice = sliceFrontmatter(content);
|
|
362
389
|
if (slice === null)
|
|
363
390
|
return null;
|
|
@@ -365,6 +392,24 @@ function rewriteContract(content, contract) {
|
|
|
365
392
|
if (document.errors.length > 0)
|
|
366
393
|
return null;
|
|
367
394
|
const current = document.toJS();
|
|
395
|
+
const dropped = (link) => isRecord(link) &&
|
|
396
|
+
dropLinks.some((drop) => drop.type === link.type && drop.target === link.target);
|
|
397
|
+
const keptLinks = Array.isArray(current.links)
|
|
398
|
+
? current.links.filter((link) => !dropped(link))
|
|
399
|
+
: current.links;
|
|
400
|
+
if (dropLinks.length > 0) {
|
|
401
|
+
if (!Array.isArray(current.links))
|
|
402
|
+
return null;
|
|
403
|
+
if (current.links.length - keptLinks.length !==
|
|
404
|
+
dropLinks.length)
|
|
405
|
+
return null;
|
|
406
|
+
for (let index = current.links.length - 1; index >= 0; index--) {
|
|
407
|
+
if (dropped(current.links[index]))
|
|
408
|
+
document.deleteIn(["links", index]);
|
|
409
|
+
}
|
|
410
|
+
if (keptLinks.length === 0)
|
|
411
|
+
document.delete("links");
|
|
412
|
+
}
|
|
368
413
|
const flowSpan = (span) => {
|
|
369
414
|
const node = document.createNode(span);
|
|
370
415
|
node.flow = true;
|
|
@@ -425,7 +470,11 @@ function rewriteContract(content, contract) {
|
|
|
425
470
|
])) {
|
|
426
471
|
const expected = key in contract
|
|
427
472
|
? contract[key]
|
|
428
|
-
:
|
|
473
|
+
: key === "links" && dropLinks.length > 0
|
|
474
|
+
? keptLinks.length > 0
|
|
475
|
+
? keptLinks
|
|
476
|
+
: undefined
|
|
477
|
+
: before[key];
|
|
429
478
|
if (!isDeepStrictEqual(after[key], expected))
|
|
430
479
|
return null;
|
|
431
480
|
}
|
|
@@ -472,6 +521,48 @@ export function applyInventoryRederivation(workspaceRoot, requirementId, expecte
|
|
|
472
521
|
summary: plan.summary,
|
|
473
522
|
};
|
|
474
523
|
}
|
|
524
|
+
function linkKeys(links) {
|
|
525
|
+
return JSON.stringify(links.map((link) => `${link.type}\u0000${link.target}`).sort());
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Apply an unsafe re-derivation a person approved: write the re-derived
|
|
529
|
+
* contract and remove exactly `expectedDrops`, the orphaned grounding links
|
|
530
|
+
* the plan listed, from the requirement's front matter. The current plan must
|
|
531
|
+
* still produce the approved contract hash and the same orphaned links, and
|
|
532
|
+
* the rewritten requirement must pass ingestion before anything is written;
|
|
533
|
+
* the grounding facts themselves are left alone.
|
|
534
|
+
*/
|
|
535
|
+
// implements REQ-kibi-proposition-complete-ingestion, REQ-cli-schema-migration
|
|
536
|
+
export function applyInventoryRederivationDroppingGrounding(workspaceRoot, requirementId, expectedContractHash, expectedDrops) {
|
|
537
|
+
const plan = planInventoryRederivation(workspaceRoot, requirementId).find((candidate) => candidate.requirementId === requirementId);
|
|
538
|
+
if (plan === undefined ||
|
|
539
|
+
!plan.rederivableByDroppingGrounding ||
|
|
540
|
+
plan.contractHash !== expectedContractHash ||
|
|
541
|
+
linkKeys(plan.orphanedGrounding) !== linkKeys(expectedDrops)) {
|
|
542
|
+
throw new Error(`Requirement ${requirementId} changed since planning; rerun kibi migrate and approve the new plan.`);
|
|
543
|
+
}
|
|
544
|
+
const absolute = path.join(workspaceRoot, plan.path);
|
|
545
|
+
const content = readText(absolute);
|
|
546
|
+
const next = content === null
|
|
547
|
+
? null
|
|
548
|
+
: rewriteContract(content, plan.contract, plan.orphanedGrounding);
|
|
549
|
+
if (next === null) {
|
|
550
|
+
throw new Error(`Requirement ${requirementId}: the re-derived inventory and the dropped grounding links could not be written without changing other frontmatter fields.`);
|
|
551
|
+
}
|
|
552
|
+
// Fail closed: the rewritten requirement must pass ingestion as sync sees it.
|
|
553
|
+
const reread = extractFromMarkdownString(next, absolute);
|
|
554
|
+
const remaining = planOne(workspaceRoot, plan.path, reread.entity, reread.relationships, readShardRelationships(workspaceRoot), new FactClaimIndex(workspaceRoot));
|
|
555
|
+
if (remaining !== null) {
|
|
556
|
+
throw new Error(`Requirement ${requirementId}: the rewrite would still fail ingestion (${remaining.errors.join("; ")}); nothing was written.`);
|
|
557
|
+
}
|
|
558
|
+
writeFileAtomically(absolute, next);
|
|
559
|
+
return {
|
|
560
|
+
requirementId,
|
|
561
|
+
path: plan.path,
|
|
562
|
+
outcome: "rederived",
|
|
563
|
+
summary: plan.summary,
|
|
564
|
+
};
|
|
565
|
+
}
|
|
475
566
|
/** Apply every safe re-derivation; unsafe ones are returned untouched. */
|
|
476
567
|
// implements REQ-kibi-proposition-complete-ingestion, REQ-cli-schema-migration
|
|
477
568
|
export function applySafeInventoryRederivations(workspaceRoot) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type InventoryRederivation } from "./inventory-rederive.js";
|
|
2
|
+
/**
|
|
3
|
+
* Suggested current status for ADR or lifecycle vocabulary found on
|
|
4
|
+
* requirements: decided or still-proposed intent stays `open`; retired
|
|
5
|
+
* intent is `closed`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SUGGESTED_REQUIREMENT_STATUS: Readonly<Record<string, string>>;
|
|
8
|
+
/** One requirement whose status is outside the vocabulary. */
|
|
9
|
+
export type RequirementStatusFinding = Readonly<{
|
|
10
|
+
requirementId: string;
|
|
11
|
+
path: string;
|
|
12
|
+
status: string;
|
|
13
|
+
/** The suggested current status; null when Kibi has no suggestion. */
|
|
14
|
+
suggestedStatus: string | null;
|
|
15
|
+
/** Inventory drift the requirement shows once it has the suggested status. */
|
|
16
|
+
latentDrift: InventoryRederivation | null;
|
|
17
|
+
}>;
|
|
18
|
+
/** Every requirement whose authored status is outside the vocabulary. */
|
|
19
|
+
export declare function planRequirementStatusMappings(workspaceRoot: string): RequirementStatusFinding[];
|
|
20
|
+
/**
|
|
21
|
+
* Set the status of one requirement from `from` to `to`, replacing only its
|
|
22
|
+
* `status` line. Refuses when the authored status is no longer `from`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function applyRequirementStatusMapping(workspaceRoot: string, relativePath: string, from: string, to: string): void;
|
|
25
|
+
//# sourceMappingURL=requirement-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirement-status.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/requirement-status.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,KAAK,qBAAqB,EAE3B,MAAM,yBAAyB,CAAC;AA8BjC;;;;GAIG;AAEH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOzE,CAAC;AAEF,8DAA8D;AAE9D,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,8EAA8E;IAC9E,WAAW,EAAE,qBAAqB,GAAG,IAAI,CAAC;CAC3C,CAAC,CAAC;AAYH,yEAAyE;AAEzE,wBAAgB,6BAA6B,CAC3C,aAAa,EAAE,MAAM,GACpB,wBAAwB,EAAE,CA8B5B;AAED;;;GAGG;AAEH,wBAAgB,6BAA6B,CAC3C,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,IAAI,CAaN"}
|