kibi-cli 2.5.2 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-operation-metadata.d.ts +1 -1
- package/dist/cli-operation-metadata.js +1 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +15 -0
- package/dist/commands/init-helpers.js +1 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +43 -0
- package/dist/entity-body-context.d.ts +132 -0
- package/dist/entity-body-context.d.ts.map +1 -0
- package/dist/entity-body-context.js +382 -0
- package/dist/extractors/markdown.d.ts +13 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +19 -2
- package/dist/intent-search.d.ts.map +1 -1
- package/dist/intent-search.js +4 -4
- package/dist/operations/bootstrap/candidate-helpers.d.ts +18 -0
- package/dist/operations/bootstrap/candidate-helpers.d.ts.map +1 -1
- package/dist/operations/bootstrap/candidate-helpers.js +35 -0
- package/dist/operations/bootstrap/candidates.d.ts.map +1 -1
- package/dist/operations/bootstrap/candidates.js +4 -2
- package/dist/operations/bootstrap/generate.d.ts.map +1 -1
- package/dist/operations/bootstrap/generate.js +24 -15
- package/dist/operations/bootstrap/intent-claims.d.ts.map +1 -1
- package/dist/operations/bootstrap/intent-claims.js +210 -5
- package/dist/operations/bootstrap/markdown-candidates.d.ts.map +1 -1
- package/dist/operations/bootstrap/markdown-candidates.js +7 -3
- package/dist/operations/bootstrap/presentation.d.ts +8 -0
- package/dist/operations/bootstrap/presentation.d.ts.map +1 -1
- package/dist/operations/bootstrap/presentation.js +66 -8
- package/dist/operations/bootstrap/types.d.ts +21 -0
- package/dist/operations/bootstrap/types.d.ts.map +1 -1
- package/dist/operations/bootstrap/types.js +10 -0
- package/dist/operations/migration/entity-body-context.d.ts +57 -0
- package/dist/operations/migration/entity-body-context.d.ts.map +1 -0
- package/dist/operations/migration/entity-body-context.js +261 -0
- package/dist/operations/migration/polarity-values.d.ts.map +1 -1
- package/dist/operations/migration/polarity-values.js +5 -2
- package/dist/operations/migration/schema6.d.ts +2 -0
- package/dist/operations/migration/schema6.d.ts.map +1 -1
- package/dist/operations/migration/schema6.js +69 -0
- package/dist/operations/modeling/logic-modeling.d.ts.map +1 -1
- package/dist/operations/modeling/logic-modeling.js +3 -1
- package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
- package/dist/operations/modeling/model-requirement.js +7 -9
- package/dist/operations/mutation/context-warning.d.ts +13 -0
- package/dist/operations/mutation/context-warning.d.ts.map +1 -0
- package/dist/operations/mutation/context-warning.js +59 -0
- package/dist/operations/mutation/origin.d.ts +2 -1
- package/dist/operations/mutation/origin.d.ts.map +1 -1
- package/dist/operations/mutation/origin.js +7 -18
- package/dist/operations/mutation/requirement-semantics.d.ts +16 -0
- package/dist/operations/mutation/requirement-semantics.d.ts.map +1 -0
- package/dist/operations/mutation/requirement-semantics.js +64 -0
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +10 -0
- package/dist/operations/mutation/stored-entity.d.ts +20 -0
- package/dist/operations/mutation/stored-entity.d.ts.map +1 -0
- package/dist/operations/mutation/stored-entity.js +51 -0
- package/dist/operations/mutation/upsert.d.ts +3 -2
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +19 -10
- package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
- package/dist/operations/mutation/validate-upsert.js +6 -1
- package/dist/operations/planning/compile-intent.d.ts +9 -0
- package/dist/operations/planning/compile-intent.d.ts.map +1 -1
- package/dist/operations/planning/compile-intent.js +49 -2
- package/dist/operations/semantic-advisor/analyze-prose.d.ts +3 -2
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +3 -41
- package/dist/operations/semantic-advisor/ingestion-boundary.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/ingestion-boundary.js +10 -1
- package/dist/operations/semantic-advisor/proposition-role.d.ts +6 -0
- package/dist/operations/semantic-advisor/proposition-role.d.ts.map +1 -0
- package/dist/operations/semantic-advisor/proposition-role.js +76 -0
- package/dist/public/operations/catalog.d.ts +78 -9
- 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 +3 -0
- package/dist/public/operations/entity-context.d.ts +51 -0
- package/dist/public/operations/entity-context.d.ts.map +1 -0
- package/dist/public/operations/entity-context.js +235 -0
- package/dist/public/operations/origin-review.d.ts +1 -1
- package/dist/public/operations/origin-review.js +2 -2
- package/dist/public/operations/specs/bootstrap.d.ts +59 -5
- package/dist/public/operations/specs/bootstrap.d.ts.map +1 -1
- package/dist/public/operations/specs/bootstrap.js +48 -6
- 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 +3 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts +1 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +10 -2
- package/dist/public/operations/specs/planning.d.ts +15 -0
- package/dist/public/operations/specs/planning.d.ts.map +1 -1
- package/dist/public/operations/specs/planning.js +15 -0
- package/dist/public/operations/specs/upsert.d.ts +3 -3
- package/dist/public/operations/specs/upsert.js +2 -2
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +7 -1
- package/dist/public/skills/kibi-bootstrap/SKILL.md +13 -7
- package/dist/public/skills/kibi-bootstrap/resources/bootstrap.md +9 -2
- package/dist/public/skills/kibi-usage/SKILL.md +56 -3
- package/dist/public/skills/kibi-usage/resources/source-authoring.md +5 -1
- package/dist/schemas/entity.schema.json +14 -1
- package/dist/search-ranking.d.ts.map +1 -1
- package/dist/search-ranking.js +7 -4
- package/dist/traceability/staged-consistency.d.ts +25 -0
- package/dist/traceability/staged-consistency.d.ts.map +1 -0
- package/dist/traceability/staged-consistency.js +92 -0
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +5 -0
- package/dist/utils/kb-manifest.d.ts +5 -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 +11 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +13 -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 -2
- package/package.json +2 -2
- package/schema/manifest.json +5 -0
- package/schema/validation.pl +14 -2
- package/src/public/operations/check-executor.ts +6 -0
- package/src/public/operations/entity-context.ts +304 -0
- package/src/public/operations/origin-review.ts +2 -2
- package/src/public/operations/specs/bootstrap.ts +52 -5
- package/src/public/operations/specs/check-rules.generated.ts +3 -1
- package/src/public/operations/specs/mutation-schemas.ts +10 -2
- package/src/public/operations/specs/planning.ts +18 -0
- package/src/public/operations/specs/upsert.ts +2 -2
- package/src/public/schemas/entity.ts +7 -1
- package/src/public/skills/kibi-bootstrap/SKILL.md +13 -7
- package/src/public/skills/kibi-bootstrap/resources/bootstrap.md +9 -2
- package/src/public/skills/kibi-usage/SKILL.md +56 -3
- package/src/public/skills/kibi-usage/resources/source-authoring.md +5 -1
- package/src/schemas/entity.schema.json +14 -1
|
@@ -31,6 +31,16 @@ export const KNOWLEDGE_SOURCE_AUTHORITIES = [
|
|
|
31
31
|
"supporting",
|
|
32
32
|
"stale",
|
|
33
33
|
];
|
|
34
|
+
/**
|
|
35
|
+
* What a harvested claim is: intended behavior, an observation about how
|
|
36
|
+
* things are today, or a question the sources leave open. Only intent can
|
|
37
|
+
* become a requirement; the others stay explicit review facts.
|
|
38
|
+
*/
|
|
39
|
+
export const INTENT_CLAIM_KINDS = [
|
|
40
|
+
"intent",
|
|
41
|
+
"observation",
|
|
42
|
+
"open_question",
|
|
43
|
+
];
|
|
34
44
|
export const BOOTSTRAP_PROVIDER_ORDER = [
|
|
35
45
|
"typed_kibi_docs",
|
|
36
46
|
"generic_repo_docs",
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** Schema 8: pin the checked meaning of requirements that never stated one. */
|
|
2
|
+
export declare const SEMANTIC_TEXT_PIN_CODE = "semantic_text_pin";
|
|
3
|
+
/** Schema 8: acknowledge current entities that lack body context. */
|
|
4
|
+
export declare const CONTEXT_MISSING_TAG_CODE = "context_missing_tag";
|
|
5
|
+
/** One authored file the schema 8 migration rewrites (front matter only). */
|
|
6
|
+
export type BodyContextTarget = Readonly<{
|
|
7
|
+
id: string;
|
|
8
|
+
type: string;
|
|
9
|
+
path: string;
|
|
10
|
+
before: string;
|
|
11
|
+
after: string;
|
|
12
|
+
}>;
|
|
13
|
+
export type BodyContextPlan = Readonly<{
|
|
14
|
+
targets: readonly BodyContextTarget[];
|
|
15
|
+
/** Files Kibi cannot edit safely, with the reason. */
|
|
16
|
+
skipped: readonly Readonly<{
|
|
17
|
+
id: string;
|
|
18
|
+
path: string;
|
|
19
|
+
reason: string;
|
|
20
|
+
}>[];
|
|
21
|
+
/** Context-less entities that already carried the tag before migration. */
|
|
22
|
+
alreadyTagged?: readonly string[];
|
|
23
|
+
}>;
|
|
24
|
+
/**
|
|
25
|
+
* Ids the schema 8 migration acknowledges: every context-less entity it tags
|
|
26
|
+
* plus those that already carried the tag. Recorded in the manifest, which is
|
|
27
|
+
* the only thing that makes the tag honored by `entity-context-missing`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function acknowledgedContextIds(plan: BodyContextPlan): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Requirements without a front-matter `semantic_text`, pinned to the value
|
|
32
|
+
* the pre-schema-8 derivation produces from the body (context sections
|
|
33
|
+
* included), so claim spans and hashes do not move when the extractor stops
|
|
34
|
+
* reading context sections. Read-only.
|
|
35
|
+
*/
|
|
36
|
+
export declare function planSemanticTextPins(workspaceRoot: string): BodyContextPlan;
|
|
37
|
+
/**
|
|
38
|
+
* Add one tag to a document's front matter, leaving every other byte
|
|
39
|
+
* unchanged. Handles an absent key, a one-line flow list and a block list of
|
|
40
|
+
* plain items; returns null for anything else or when the edit would not read
|
|
41
|
+
* back as exactly that one added tag.
|
|
42
|
+
*/
|
|
43
|
+
export declare function withAddedTag(content: string, tag: string): string | null;
|
|
44
|
+
/**
|
|
45
|
+
* Current requirements, scenarios, tests, ADRs and observation facts whose
|
|
46
|
+
* body fails the context check and that are not yet tagged, to be tagged
|
|
47
|
+
* `review:context-missing`. No prose is written: the tag only acknowledges the
|
|
48
|
+
* gap. Read-only.
|
|
49
|
+
*/
|
|
50
|
+
export declare function planContextMissingTags(workspaceRoot: string): BodyContextPlan;
|
|
51
|
+
/** Count targets by entity type, sorted by type. */
|
|
52
|
+
export declare function countByType(targets: readonly Pick<BodyContextTarget, "type">[]): Record<string, number>;
|
|
53
|
+
/** Pin semantic_text, then return how many requirements were rewritten. */
|
|
54
|
+
export declare function applySemanticTextPins(workspaceRoot: string): number;
|
|
55
|
+
/** Tag entities that lack context, then return how many were rewritten. */
|
|
56
|
+
export declare function applyContextMissingTags(workspaceRoot: string): number;
|
|
57
|
+
//# sourceMappingURL=entity-body-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-body-context.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/entity-body-context.ts"],"names":[],"mappings":"AA0CA,+EAA+E;AAE/E,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAC1D,qEAAqE;AAErE,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAE9D,6EAA6E;AAE7E,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAGH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtC,sDAAsD;IACtD,OAAO,EAAE,SAAS,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IAC3E,2EAA2E;IAC3E,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC,CAAC;AAEH;;;;GAIG;AAEH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAOtE;AAED;;;;;GAKG;AAEH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe,CA8B3E;AAMD;;;;;GAKG;AAEH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmExE;AAED;;;;;GAKG;AAEH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe,CAkC7E;AAED,oDAAoD;AAEpD,wBAAgB,WAAW,CACzB,OAAO,EAAE,SAAS,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,EAAE,GAClD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxB;AASD,2EAA2E;AAE3E,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,2EAA2E;AAE3E,wBAAgB,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAKrE"}
|
|
@@ -0,0 +1,261 @@
|
|
|
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
|
+
import { isDeepStrictEqual } from "node:util";
|
|
19
|
+
import { load as loadYaml } from "js-yaml";
|
|
20
|
+
import { CONTEXT_MISSING_TAG, assessContext, isContextAcknowledged, } from "../../entity-body-context.js";
|
|
21
|
+
import { legacyRequirementSemanticText } from "../../extractors/markdown.js";
|
|
22
|
+
import { authoredSupersededIds, contextEntityOf, isCurrentAuthoredEntity, listContextAuthoredEntities, readAuthoredEntity, } from "../../public/operations/entity-context.js";
|
|
23
|
+
import { readKbManifest, writeKbManifest } from "../../utils/kb-manifest.js";
|
|
24
|
+
import { listLaneMarkdownFiles, readText, sliceFrontmatter, withTopLevelField, writeFileAtomically, } from "./kb-sources.js";
|
|
25
|
+
/** Schema 8: pin the checked meaning of requirements that never stated one. */
|
|
26
|
+
// implements REQ-kb-entity-body-context, REQ-cli-schema-migration
|
|
27
|
+
export const SEMANTIC_TEXT_PIN_CODE = "semantic_text_pin";
|
|
28
|
+
/** Schema 8: acknowledge current entities that lack body context. */
|
|
29
|
+
// implements REQ-kb-entity-body-context, REQ-cli-schema-migration
|
|
30
|
+
export const CONTEXT_MISSING_TAG_CODE = "context_missing_tag";
|
|
31
|
+
/**
|
|
32
|
+
* Ids the schema 8 migration acknowledges: every context-less entity it tags
|
|
33
|
+
* plus those that already carried the tag. Recorded in the manifest, which is
|
|
34
|
+
* the only thing that makes the tag honored by `entity-context-missing`.
|
|
35
|
+
*/
|
|
36
|
+
// implements REQ-kb-entity-body-context, REQ-cli-schema-migration
|
|
37
|
+
export function acknowledgedContextIds(plan) {
|
|
38
|
+
return [
|
|
39
|
+
...new Set([
|
|
40
|
+
...plan.targets.map((target) => target.id),
|
|
41
|
+
...(plan.alreadyTagged ?? []),
|
|
42
|
+
]),
|
|
43
|
+
].sort();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Requirements without a front-matter `semantic_text`, pinned to the value
|
|
47
|
+
* the pre-schema-8 derivation produces from the body (context sections
|
|
48
|
+
* included), so claim spans and hashes do not move when the extractor stops
|
|
49
|
+
* reading context sections. Read-only.
|
|
50
|
+
*/
|
|
51
|
+
// implements REQ-kb-entity-body-context, REQ-cli-schema-migration
|
|
52
|
+
export function planSemanticTextPins(workspaceRoot) {
|
|
53
|
+
const targets = [];
|
|
54
|
+
const skipped = [];
|
|
55
|
+
for (const file of listLaneMarkdownFiles(workspaceRoot, ["requirements"])) {
|
|
56
|
+
const before = readText(file.absolutePath);
|
|
57
|
+
if (before === null)
|
|
58
|
+
continue;
|
|
59
|
+
const entity = readAuthoredEntity(before, file.relativePath);
|
|
60
|
+
if (entity === null || entity.type !== "req")
|
|
61
|
+
continue;
|
|
62
|
+
const pinned = entity.data.semantic_text;
|
|
63
|
+
if (typeof pinned === "string" && pinned.trim() !== "")
|
|
64
|
+
continue;
|
|
65
|
+
const derived = legacyRequirementSemanticText(entity.body);
|
|
66
|
+
if (derived === "")
|
|
67
|
+
continue;
|
|
68
|
+
const after = withTopLevelField(before, "semantic_text", derived);
|
|
69
|
+
if (after === null) {
|
|
70
|
+
skipped.push({
|
|
71
|
+
id: entity.id,
|
|
72
|
+
path: file.relativePath,
|
|
73
|
+
reason: "semantic_text could not be edited safely",
|
|
74
|
+
});
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
targets.push({
|
|
78
|
+
id: entity.id,
|
|
79
|
+
type: entity.type,
|
|
80
|
+
path: file.relativePath,
|
|
81
|
+
before,
|
|
82
|
+
after,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return { targets, skipped };
|
|
86
|
+
}
|
|
87
|
+
function isRecord(value) {
|
|
88
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Add one tag to a document's front matter, leaving every other byte
|
|
92
|
+
* unchanged. Handles an absent key, a one-line flow list and a block list of
|
|
93
|
+
* plain items; returns null for anything else or when the edit would not read
|
|
94
|
+
* back as exactly that one added tag.
|
|
95
|
+
*/
|
|
96
|
+
// implements REQ-kb-entity-body-context, REQ-cli-schema-migration
|
|
97
|
+
export function withAddedTag(content, tag) {
|
|
98
|
+
const slice = sliceFrontmatter(content);
|
|
99
|
+
if (slice === null)
|
|
100
|
+
return null;
|
|
101
|
+
let before;
|
|
102
|
+
try {
|
|
103
|
+
before = loadYaml(slice.text);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
if (!isRecord(before))
|
|
109
|
+
return null;
|
|
110
|
+
const existing = before.tags;
|
|
111
|
+
if (existing !== undefined && existing !== null && !Array.isArray(existing))
|
|
112
|
+
return null;
|
|
113
|
+
const eol = slice.eol;
|
|
114
|
+
const lines = slice.text.split(/\r?\n/);
|
|
115
|
+
// The text ends with a line break, so the last element is empty.
|
|
116
|
+
const body = lines.slice(0, -1);
|
|
117
|
+
const keyIndex = body.findIndex((line) => /^tags[ \t]*:/.test(line));
|
|
118
|
+
let next;
|
|
119
|
+
if (keyIndex < 0) {
|
|
120
|
+
next = [...body, "tags:", ` - ${tag}`];
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
const line = body[keyIndex] ?? "";
|
|
124
|
+
const rest = line.slice(line.indexOf(":") + 1).trim();
|
|
125
|
+
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
126
|
+
const inner = rest.slice(1, -1).trim();
|
|
127
|
+
const edited = `${line.slice(0, line.indexOf(":") + 1)} [${inner === "" ? tag : `${inner}, ${tag}`}]`;
|
|
128
|
+
next = [...body.slice(0, keyIndex), edited, ...body.slice(keyIndex + 1)];
|
|
129
|
+
}
|
|
130
|
+
else if (rest === "" || rest === "null" || rest === "~") {
|
|
131
|
+
let end = keyIndex + 1;
|
|
132
|
+
let indent = " ";
|
|
133
|
+
while (end < body.length) {
|
|
134
|
+
const item = /^([ \t]*)-[ \t]+\S/.exec(body[end] ?? "");
|
|
135
|
+
if (item === null)
|
|
136
|
+
break;
|
|
137
|
+
if (end === keyIndex + 1)
|
|
138
|
+
indent = item[1] ?? "";
|
|
139
|
+
end += 1;
|
|
140
|
+
}
|
|
141
|
+
const head = rest === "" ? line : `${line.slice(0, line.indexOf(":") + 1)}`;
|
|
142
|
+
next = [
|
|
143
|
+
...body.slice(0, keyIndex),
|
|
144
|
+
head,
|
|
145
|
+
...body.slice(keyIndex + 1, end),
|
|
146
|
+
`${indent}- ${tag}`,
|
|
147
|
+
...body.slice(end),
|
|
148
|
+
];
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const text = `${next.join(eol)}${eol}`;
|
|
155
|
+
try {
|
|
156
|
+
const after = loadYaml(text);
|
|
157
|
+
if (!isRecord(after))
|
|
158
|
+
return null;
|
|
159
|
+
const { tags: beforeTags, ...beforeRest } = before;
|
|
160
|
+
const { tags: afterTags, ...afterRest } = after;
|
|
161
|
+
const expected = [...(Array.isArray(beforeTags) ? beforeTags : []), tag];
|
|
162
|
+
if (!isDeepStrictEqual(afterTags, expected) ||
|
|
163
|
+
!isDeepStrictEqual(beforeRest, afterRest)) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
return `${slice.prefix}${text}${slice.suffix}`;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Current requirements, scenarios, tests, ADRs and observation facts whose
|
|
174
|
+
* body fails the context check and that are not yet tagged, to be tagged
|
|
175
|
+
* `review:context-missing`. No prose is written: the tag only acknowledges the
|
|
176
|
+
* gap. Read-only.
|
|
177
|
+
*/
|
|
178
|
+
// implements REQ-kb-entity-body-context, REQ-cli-schema-migration
|
|
179
|
+
export function planContextMissingTags(workspaceRoot) {
|
|
180
|
+
const entities = listContextAuthoredEntities(workspaceRoot);
|
|
181
|
+
const superseded = authoredSupersededIds(workspaceRoot, entities);
|
|
182
|
+
const targets = [];
|
|
183
|
+
const skipped = [];
|
|
184
|
+
const alreadyTagged = [];
|
|
185
|
+
for (const entity of entities) {
|
|
186
|
+
if (!isCurrentAuthoredEntity(entity, superseded))
|
|
187
|
+
continue;
|
|
188
|
+
const view = contextEntityOf(entity);
|
|
189
|
+
if (assessContext(entity.type, entity.body, view).ok)
|
|
190
|
+
continue;
|
|
191
|
+
if (isContextAcknowledged(view.tags)) {
|
|
192
|
+
alreadyTagged.push(entity.id);
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
const before = readText(`${workspaceRoot}/${entity.path}`);
|
|
196
|
+
if (before === null)
|
|
197
|
+
continue;
|
|
198
|
+
const after = withAddedTag(before, CONTEXT_MISSING_TAG);
|
|
199
|
+
if (after === null) {
|
|
200
|
+
skipped.push({
|
|
201
|
+
id: entity.id,
|
|
202
|
+
path: entity.path,
|
|
203
|
+
reason: "tags could not be edited safely",
|
|
204
|
+
});
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
targets.push({
|
|
208
|
+
id: entity.id,
|
|
209
|
+
type: entity.type,
|
|
210
|
+
path: entity.path,
|
|
211
|
+
before,
|
|
212
|
+
after,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
return { targets, skipped, alreadyTagged };
|
|
216
|
+
}
|
|
217
|
+
/** Count targets by entity type, sorted by type. */
|
|
218
|
+
// implements REQ-kb-entity-body-context, REQ-cli-schema-migration
|
|
219
|
+
export function countByType(targets) {
|
|
220
|
+
const counts = {};
|
|
221
|
+
for (const target of targets) {
|
|
222
|
+
counts[target.type] = (counts[target.type] ?? 0) + 1;
|
|
223
|
+
}
|
|
224
|
+
return Object.fromEntries(Object.entries(counts).sort(([left], [right]) => left.localeCompare(right)));
|
|
225
|
+
}
|
|
226
|
+
function applyPlan(workspaceRoot, plan) {
|
|
227
|
+
for (const target of plan.targets) {
|
|
228
|
+
writeFileAtomically(`${workspaceRoot}/${target.path}`, target.after);
|
|
229
|
+
}
|
|
230
|
+
return plan.targets.length;
|
|
231
|
+
}
|
|
232
|
+
/** Pin semantic_text, then return how many requirements were rewritten. */
|
|
233
|
+
// implements REQ-kb-entity-body-context, REQ-cli-schema-migration
|
|
234
|
+
export function applySemanticTextPins(workspaceRoot) {
|
|
235
|
+
return applyPlan(workspaceRoot, planSemanticTextPins(workspaceRoot));
|
|
236
|
+
}
|
|
237
|
+
/** Tag entities that lack context, then return how many were rewritten. */
|
|
238
|
+
// implements REQ-kb-entity-body-context, REQ-cli-schema-migration
|
|
239
|
+
export function applyContextMissingTags(workspaceRoot) {
|
|
240
|
+
const plan = planContextMissingTags(workspaceRoot);
|
|
241
|
+
const count = applyPlan(workspaceRoot, plan);
|
|
242
|
+
recordContextAcknowledged(workspaceRoot, acknowledgedContextIds(plan));
|
|
243
|
+
return count;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Record the acknowledged ids in the manifest. The tag alone is never honored
|
|
247
|
+
* by `entity-context-missing`; the manifest is what the migration vouches with.
|
|
248
|
+
*/
|
|
249
|
+
function recordContextAcknowledged(workspaceRoot, ids) {
|
|
250
|
+
if (ids.length === 0)
|
|
251
|
+
return;
|
|
252
|
+
const manifest = readKbManifest(workspaceRoot);
|
|
253
|
+
if (manifest === null)
|
|
254
|
+
return;
|
|
255
|
+
writeKbManifest(workspaceRoot, {
|
|
256
|
+
...manifest,
|
|
257
|
+
contextAcknowledged: [
|
|
258
|
+
...new Set([...(manifest.contextAcknowledged ?? []), ...ids]),
|
|
259
|
+
].sort(),
|
|
260
|
+
});
|
|
261
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polarity-values.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/polarity-values.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,4BAA4B,4BAA4B,CAAC;AAEtE,6EAA6E;AAE7E,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,GACpB,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"polarity-values.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/polarity-values.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,4BAA4B,4BAA4B,CAAC;AAEtE,6EAA6E;AAE7E,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,GACpB,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAiExE;AAGD,wBAAgB,0BAA0B,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAKxE"}
|
|
@@ -35,7 +35,10 @@ export function planPolarityValueBackfill(workspaceRoot) {
|
|
|
35
35
|
typeof data.property_key !== "string")
|
|
36
36
|
throw new Error(`Cannot migrate polarity fact ${file.relativePath}: subject_key and property_key are required`);
|
|
37
37
|
const after = `${slice.prefix}${slice.text}operator: eq${slice.eol}value_type: bool${slice.eol}value_bool: true${slice.eol}${slice.suffix}`;
|
|
38
|
-
const
|
|
38
|
+
const afterFrontmatter = sliceFrontmatter(after);
|
|
39
|
+
if (!afterFrontmatter)
|
|
40
|
+
throw new Error(`Polarity migration could not verify ${file.relativePath}`);
|
|
41
|
+
const parsed = loadYaml(afterFrontmatter.text);
|
|
39
42
|
if (parsed.operator !== "eq" ||
|
|
40
43
|
parsed.value_type !== "bool" ||
|
|
41
44
|
parsed.value_bool !== true)
|
|
@@ -43,7 +46,7 @@ export function planPolarityValueBackfill(workspaceRoot) {
|
|
|
43
46
|
targets.push({
|
|
44
47
|
id: typeof data.id === "string"
|
|
45
48
|
? data.id
|
|
46
|
-
: file.relativePath.split("/").at(-1).slice(0, -3),
|
|
49
|
+
: (file.relativePath.split("/").at(-1) ?? "").slice(0, -3),
|
|
47
50
|
path: file.relativePath,
|
|
48
51
|
before,
|
|
49
52
|
after,
|
|
@@ -2,6 +2,8 @@ import { type MigrationAction } from "../../public/operations/migration-plan.js"
|
|
|
2
2
|
import { CLOSE_SUPERSEDED_REQUIREMENTS_CODE, MIGRATION_SYNC_ACTION_ID, MIGRATION_SYNC_CODE, SOURCE_PATH_REWRITE_CODE } from "../../public/operations/schema6-check-actions.js";
|
|
3
3
|
/** The KB schema generation that introduced entity `origin`. */
|
|
4
4
|
export declare const ORIGIN_SCHEMA_VERSION = 6;
|
|
5
|
+
/** The KB schema generation that requires body context on current entities. */
|
|
6
|
+
export declare const BODY_CONTEXT_SCHEMA_VERSION = 8;
|
|
5
7
|
/** Automatic: re-derive a drifted inventory with the current advisor. */
|
|
6
8
|
export declare const SEMANTIC_INVENTORY_REDERIVE_CODE = "semantic_inventory_rederive";
|
|
7
9
|
/** Review: a drifted inventory Kibi cannot re-derive safely. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema6.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/schema6.ts"],"names":[],"mappings":"AAuBA,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAEL,kCAAkC,EAClC,wBAAwB,EACxB,mBAAmB,EAEnB,wBAAwB,EAOzB,MAAM,kDAAkD,CAAC;
|
|
1
|
+
{"version":3,"file":"schema6.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/schema6.ts"],"names":[],"mappings":"AAuBA,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAEL,kCAAkC,EAClC,wBAAwB,EACxB,mBAAmB,EAEnB,wBAAwB,EAOzB,MAAM,kDAAkD,CAAC;AAoC1D,gEAAgE;AAEhE,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,+EAA+E;AAE/E,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,yEAAyE;AAEzE,eAAO,MAAM,gCAAgC,gCAAgC,CAAC;AAC9E,gEAAgE;AAEhE,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAC1E,yEAAyE;AAEzE,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AAEpE,eAAO,MAAM,gCAAgC,2BAA2B,CAAC;AACzE,OAAO,EACL,kCAAkC,EAClC,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,GACzB,CAAC;AAsEF;;;GAGG;AAEH,wBAAgB,+BAA+B,CAC7C,aAAa,EAAE,MAAM,GACpB,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAsDnE;AAGD,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IACpC,uDAAuD;IACvD,sBAAsB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC,CAAC,CAAC;AAEH;;;;;;GAMG;AAEH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,GAAG,wBAAwB,CA6J3B;AAED;;;;;;GAMG;AAEH,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG;IAClE,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,sBAAsB,EAAE,MAAM,EAAE,CAAC;CAClC,CAoCA;AAED,qEAAqE;AAErE,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,eAAe,CAEjB;AA0CD,KAAK,YAAY,GAAG,QAAQ,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC,CAAC;AAEH,4DAA4D;AAE5D,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CAsEf;AAGD,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAStD,CAAC"}
|
|
@@ -20,6 +20,7 @@ import { extractFromMarkdown, } from "../../extractors/markdown.js";
|
|
|
20
20
|
import { migrationAction, } from "../../public/operations/migration-plan.js";
|
|
21
21
|
import { CLOSE_SUPERSEDED_REQUIREMENTS_ACTION_ID, CLOSE_SUPERSEDED_REQUIREMENTS_CODE, MIGRATION_SYNC_ACTION_ID, MIGRATION_SYNC_CODE, SOURCE_PATH_REWRITE_ACTION_ID, SOURCE_PATH_REWRITE_CODE, closeSupersededRequirementsActionInput, exceptionUnapprovedActionInput, migrationSyncActionInput, sourcePathReviewActionInput, sourcePathRewriteActionInput, supersessionCycleReviewActionInput, } from "../../public/operations/schema6-check-actions.js";
|
|
22
22
|
import { readAllShards } from "../../relationships/shards.js";
|
|
23
|
+
import { CONTEXT_MISSING_TAG_CODE, SEMANTIC_TEXT_PIN_CODE, applyContextMissingTags, applySemanticTextPins, countByType, planContextMissingTags, planSemanticTextPins, } from "./entity-body-context.js";
|
|
23
24
|
import { applyInventoryRederivation, planInventoryRederivation, } from "./inventory-rederive.js";
|
|
24
25
|
import { listLaneMarkdownFiles } from "./kb-sources.js";
|
|
25
26
|
import { applyOriginBackfill, planOriginBackfill } from "./origin-backfill.js";
|
|
@@ -29,6 +30,9 @@ import { applySupersededClosures, planSupersededClosures, } from "./superseded-c
|
|
|
29
30
|
/** The KB schema generation that introduced entity `origin`. */
|
|
30
31
|
// implements REQ-kibi-schema6-migration, REQ-cli-schema-migration
|
|
31
32
|
export const ORIGIN_SCHEMA_VERSION = 6;
|
|
33
|
+
/** The KB schema generation that requires body context on current entities. */
|
|
34
|
+
// implements REQ-kb-entity-body-context, REQ-cli-schema-migration
|
|
35
|
+
export const BODY_CONTEXT_SCHEMA_VERSION = 8;
|
|
32
36
|
/** Automatic: re-derive a drifted inventory with the current advisor. */
|
|
33
37
|
// implements REQ-kibi-schema6-migration, REQ-cli-schema-migration
|
|
34
38
|
export const SEMANTIC_INVENTORY_REDERIVE_CODE = "semantic_inventory_rederive";
|
|
@@ -190,6 +194,61 @@ export function buildSchema6MigrationFragment(input) {
|
|
|
190
194
|
},
|
|
191
195
|
}));
|
|
192
196
|
}
|
|
197
|
+
// Schema 8: pin the checked meaning, then acknowledge missing context. A
|
|
198
|
+
// missing or invalid version upgrades through every step, so it is planned.
|
|
199
|
+
if (input.currentSchemaVersion === null ||
|
|
200
|
+
input.currentSchemaVersion < BODY_CONTEXT_SCHEMA_VERSION) {
|
|
201
|
+
const pins = planSemanticTextPins(input.workspaceRoot);
|
|
202
|
+
if (pins.targets.length > 0) {
|
|
203
|
+
const id = "semantic-text-pin";
|
|
204
|
+
sourceRewriteActionIds.push(id);
|
|
205
|
+
actions.push(migrationAction({
|
|
206
|
+
id,
|
|
207
|
+
code: SEMANTIC_TEXT_PIN_CODE,
|
|
208
|
+
category: "schema",
|
|
209
|
+
safety: "automatic",
|
|
210
|
+
autoApplicable: true,
|
|
211
|
+
invocation: {
|
|
212
|
+
kind: "cli",
|
|
213
|
+
command_argv: ["kibi", "migrate", "--yes"],
|
|
214
|
+
},
|
|
215
|
+
affectedEntityIds: pins.targets.map((row) => row.id),
|
|
216
|
+
affectedFiles: pins.targets.map((row) => row.path),
|
|
217
|
+
postconditions: [{ requirementsWithoutSemanticText: 0 }],
|
|
218
|
+
evidence: {
|
|
219
|
+
reason: "Schema 8 stops reading context sections (Context, Rationale, Why, Background, Source, Notes, Evidence) as part of a requirement's meaning. Requirements that never stated semantic_text get the value the old derivation produced, so claim spans and hashes do not move.",
|
|
220
|
+
count: pins.targets.length,
|
|
221
|
+
preserves: "every other front matter key and the body bytes",
|
|
222
|
+
},
|
|
223
|
+
}));
|
|
224
|
+
}
|
|
225
|
+
const tags = planContextMissingTags(input.workspaceRoot);
|
|
226
|
+
if (tags.targets.length > 0) {
|
|
227
|
+
const id = "context-missing-tag";
|
|
228
|
+
sourceRewriteActionIds.push(id);
|
|
229
|
+
actions.push(migrationAction({
|
|
230
|
+
id,
|
|
231
|
+
code: CONTEXT_MISSING_TAG_CODE,
|
|
232
|
+
category: "schema",
|
|
233
|
+
safety: "automatic",
|
|
234
|
+
autoApplicable: true,
|
|
235
|
+
invocation: {
|
|
236
|
+
kind: "cli",
|
|
237
|
+
command_argv: ["kibi", "migrate", "--yes"],
|
|
238
|
+
},
|
|
239
|
+
dependsOn: pins.targets.length > 0 ? ["semantic-text-pin"] : [],
|
|
240
|
+
affectedEntityIds: tags.targets.map((row) => row.id),
|
|
241
|
+
affectedFiles: tags.targets.map((row) => row.path),
|
|
242
|
+
postconditions: [{ rule: "entity-context-missing", findings: 0 }],
|
|
243
|
+
evidence: {
|
|
244
|
+
reason: "Schema 8 blocks current requirements, scenarios, tests, ADRs and observation facts whose body states no context. Existing ones are tagged review:context-missing (acknowledged legacy, counted by entity-context-acknowledged); no prose is written and no reason is invented.",
|
|
245
|
+
count: tags.targets.length,
|
|
246
|
+
byType: countByType(tags.targets),
|
|
247
|
+
preserves: "every other front matter key and the body bytes",
|
|
248
|
+
},
|
|
249
|
+
}));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
193
252
|
const drift = planInventoryRederivation(input.workspaceRoot);
|
|
194
253
|
for (const plan of drift) {
|
|
195
254
|
const action = plan.safe ? rederiveAction(plan) : reviewAction(plan);
|
|
@@ -330,6 +389,14 @@ export async function applySchema6MigrationAction(action, context) {
|
|
|
330
389
|
applyPolarityValueBackfill(context.workspaceRoot);
|
|
331
390
|
return;
|
|
332
391
|
}
|
|
392
|
+
case SEMANTIC_TEXT_PIN_CODE: {
|
|
393
|
+
applySemanticTextPins(context.workspaceRoot);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
case CONTEXT_MISSING_TAG_CODE: {
|
|
397
|
+
applyContextMissingTags(context.workspaceRoot);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
333
400
|
case SEMANTIC_INVENTORY_REDERIVE_CODE: {
|
|
334
401
|
const requirementId = action.affectedEntityIds[0];
|
|
335
402
|
if (requirementId === undefined)
|
|
@@ -371,6 +438,8 @@ export async function applySchema6MigrationAction(action, context) {
|
|
|
371
438
|
// implements REQ-kibi-schema6-migration, REQ-cli-schema-migration
|
|
372
439
|
export const SCHEMA6_AUTOMATIC_CODES = new Set([
|
|
373
440
|
POLARITY_VALUE_BACKFILL_CODE,
|
|
441
|
+
SEMANTIC_TEXT_PIN_CODE,
|
|
442
|
+
CONTEXT_MISSING_TAG_CODE,
|
|
374
443
|
SEMANTIC_INVENTORY_REDERIVE_CODE,
|
|
375
444
|
ENTITY_ORIGIN_BACKFILL_CODE,
|
|
376
445
|
CLOSE_SUPERSEDED_REQUIREMENTS_CODE,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logic-modeling.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/logic-modeling.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EAIjB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"logic-modeling.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/logic-modeling.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EAIjB,MAAM,mBAAmB,CAAC;AAS3B,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACpD;AAUD,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,mBAAmB,GACzB,oBAAoB,CAoHtB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { logicSemanticKey, utf8Span, validateLogicIr, } from "../../logic/ir.js";
|
|
3
3
|
import { modeledClaimRole, normalizeSemanticClause, semanticClaimKey, } from "../semantic-advisor/clauses.js";
|
|
4
|
+
import { advisorPropositionRole } from "../semantic-advisor/proposition-role.js";
|
|
4
5
|
import { semanticSourceHash } from "../semantic-advisor/shared.js";
|
|
5
6
|
function shortId(value) {
|
|
6
7
|
return createHash("sha256")
|
|
@@ -98,7 +99,8 @@ export function buildLogicApplyPlan(input) {
|
|
|
98
99
|
{
|
|
99
100
|
claim_key: claimKey,
|
|
100
101
|
claim_text: claimText,
|
|
101
|
-
role:
|
|
102
|
+
role: advisorPropositionRole(input.text.trim(), claimKey) ??
|
|
103
|
+
modeledClaimRole(claimText, validation.normalized.modality),
|
|
102
104
|
status: "modeled",
|
|
103
105
|
span,
|
|
104
106
|
semantic_key: semanticKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-requirement.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/model-requirement.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAgBjF,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAUhC,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAkNhC,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,GACxB,CAAC;AAIF,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,GACA,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"model-requirement.d.ts","sourceRoot":"","sources":["../../../src/operations/modeling/model-requirement.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAgBjF,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAUhC,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAkNhC,OAAO,EACL,iCAAiC,EACjC,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,GACxB,CAAC;AAIF,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,GACA,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA+CzB;AAwOD,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxB;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,oBAAoB,EAC1B,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,sBAAsB,CAAC,CAgHjC;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,sBAAsB,CAAC,CAajC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { buildStrictWriteSet, } from "../../public/check-types.js";
|
|
2
2
|
import { readKbManifestStatus } from "../../utils/kb-manifest.js";
|
|
3
3
|
import { isConventionalSubjectKey, normalizeSubjectKey, } from "../../utils/strict-modeling.js";
|
|
4
|
-
import {
|
|
5
|
-
import { extractSemanticClauses, modeledClaimRole, normalizeSemanticClause, semanticClaimKey, } from "../semantic-advisor/clauses.js";
|
|
4
|
+
import { modeledClaimRole, normalizeSemanticClause, semanticClaimKey, } from "../semantic-advisor/clauses.js";
|
|
6
5
|
import { detectConditionalRule } from "../semantic-advisor/conditional-rules.js";
|
|
6
|
+
import { advisorPropositionRole } from "../semantic-advisor/proposition-role.js";
|
|
7
7
|
import { semanticSourceHash } from "../semantic-advisor/shared.js";
|
|
8
8
|
import { buildLogicApplyPlan } from "./logic-modeling.js";
|
|
9
9
|
import { strictWriteSetToApplyPlan, writeSetPrimaryEntityId, } from "./requirement-applyplan.js";
|
|
@@ -198,7 +198,9 @@ export function annotateModelRequirementStep(step, context) {
|
|
|
198
198
|
{
|
|
199
199
|
claim_key: context.claimKey,
|
|
200
200
|
claim_text: normalizedClaimText,
|
|
201
|
-
role:
|
|
201
|
+
role: advisorPropositionRole(claimText, context.claimKey, [
|
|
202
|
+
claimText,
|
|
203
|
+
]) ?? modeledClaimRole(claimText),
|
|
202
204
|
status: "modeled",
|
|
203
205
|
span: {
|
|
204
206
|
start: 0,
|
|
@@ -235,10 +237,6 @@ function unresolvedObservationStep(step) {
|
|
|
235
237
|
// ingestion compares the persisted inventory with it. A rule modality alone
|
|
236
238
|
// would call "X must not happen unless C" normative where the advisor reads an
|
|
237
239
|
// exception, so the role comes from the advisor's own clause analysis.
|
|
238
|
-
function advisorRole(semanticText, claimKey) {
|
|
239
|
-
const clause = extractSemanticClauses(semanticText).find((entry) => entry.claim_key === claimKey);
|
|
240
|
-
return clause ? propositionRole(clause.text, clause.normative) : null;
|
|
241
|
-
}
|
|
242
240
|
function withAdvisorRoles(plan) {
|
|
243
241
|
return plan.map((step) => {
|
|
244
242
|
if (step.type !== "req")
|
|
@@ -257,7 +255,7 @@ function withAdvisorRoles(plan) {
|
|
|
257
255
|
return entry;
|
|
258
256
|
const row = entry;
|
|
259
257
|
const role = typeof row.claim_key === "string"
|
|
260
|
-
?
|
|
258
|
+
? advisorPropositionRole(semanticText, row.claim_key)
|
|
261
259
|
: null;
|
|
262
260
|
return role === null ? row : { ...row, role };
|
|
263
261
|
}),
|
|
@@ -351,7 +349,7 @@ async function unresolvedConditionalResult(args, extracted, reason, workspaceRoo
|
|
|
351
349
|
{
|
|
352
350
|
claim_key: claimKey,
|
|
353
351
|
claim_text: claimText,
|
|
354
|
-
role:
|
|
352
|
+
role: advisorPropositionRole(semanticText, claimKey) ??
|
|
355
353
|
modeledClaimRole(claimText),
|
|
356
354
|
status: "ontology_gap",
|
|
357
355
|
span: {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { UpsertInput } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The body the authored document has, or will have, after this upsert: the
|
|
4
|
+
* written file when there is one, the supplied body, the preserved body of
|
|
5
|
+
* the entity's existing document, or the default a new requirement gets.
|
|
6
|
+
*/
|
|
7
|
+
export declare function upsertDocumentBody(input: UpsertInput, entity: Readonly<Record<string, unknown>>, workspaceRoot: string, writtenPath?: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* kb_upsert warning for a written entity whose body lacks context. The same
|
|
10
|
+
* finding blocks `kb_check` as entity-context-missing, so agents see it first.
|
|
11
|
+
*/
|
|
12
|
+
export declare function entityContextWarnings(input: UpsertInput, entity: Readonly<Record<string, unknown>>, workspaceRoot: string, writtenPath?: string): readonly string[];
|
|
13
|
+
//# sourceMappingURL=context-warning.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-warning.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/context-warning.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAgB9C;;;;GAIG;AAEH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,aAAa,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAYR;AAED;;;GAGG;AAEH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,aAAa,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,GACnB,SAAS,MAAM,EAAE,CA2BnB"}
|