kibi-cli 2.20.0 → 2.21.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.
Files changed (126) hide show
  1. package/dist/cli-operation-metadata.d.ts +1 -1
  2. package/dist/cli-operation-metadata.js +1 -1
  3. package/dist/commands/doctor.js +13 -1
  4. package/dist/commands/init.d.ts.map +1 -1
  5. package/dist/commands/init.js +15 -3
  6. package/dist/commands/legacy-storage-migration.d.ts.map +1 -1
  7. package/dist/commands/legacy-storage-migration.js +26 -1
  8. package/dist/commands/migrate.d.ts +2 -0
  9. package/dist/commands/migrate.d.ts.map +1 -1
  10. package/dist/commands/migrate.js +155 -11
  11. package/dist/commands/sync/discovery.d.ts.map +1 -1
  12. package/dist/commands/sync/discovery.js +14 -2
  13. package/dist/commands/sync/persistence.d.ts.map +1 -1
  14. package/dist/commands/sync/persistence.js +4 -0
  15. package/dist/decision-firmness.d.ts +39 -0
  16. package/dist/decision-firmness.d.ts.map +1 -0
  17. package/dist/decision-firmness.js +115 -0
  18. package/dist/extractors/markdown.d.ts +2 -0
  19. package/dist/extractors/markdown.d.ts.map +1 -1
  20. package/dist/extractors/markdown.js +16 -1
  21. package/dist/operations/migration/kb-sources.d.ts +5 -1
  22. package/dist/operations/migration/kb-sources.d.ts.map +1 -1
  23. package/dist/operations/migration/kb-sources.js +28 -1
  24. package/dist/operations/migration/schema6.d.ts +2 -0
  25. package/dist/operations/migration/schema6.d.ts.map +1 -1
  26. package/dist/operations/migration/schema6.js +44 -1
  27. package/dist/operations/migration/supersedes-reason.d.ts +26 -0
  28. package/dist/operations/migration/supersedes-reason.d.ts.map +1 -0
  29. package/dist/operations/migration/supersedes-reason.js +69 -0
  30. package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
  31. package/dist/operations/modeling/predicate-applyplan.js +10 -2
  32. package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
  33. package/dist/operations/modeling/predicate-loader.js +11 -0
  34. package/dist/operations/modeling/predicate-types.d.ts +32 -1
  35. package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
  36. package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
  37. package/dist/operations/modeling/suggest-predicates.js +175 -35
  38. package/dist/operations/mutation/delete.d.ts +5 -1
  39. package/dist/operations/mutation/delete.d.ts.map +1 -1
  40. package/dist/operations/mutation/delete.js +223 -17
  41. package/dist/operations/mutation/serialization.d.ts.map +1 -1
  42. package/dist/operations/mutation/serialization.js +1 -0
  43. package/dist/operations/mutation/source-authoring.d.ts +8 -0
  44. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  45. package/dist/operations/mutation/source-authoring.js +33 -0
  46. package/dist/operations/mutation/types.d.ts +37 -0
  47. package/dist/operations/mutation/types.d.ts.map +1 -1
  48. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  49. package/dist/operations/mutation/upsert.js +54 -2
  50. package/dist/operations/mutation/validation.d.ts.map +1 -1
  51. package/dist/operations/mutation/validation.js +2 -1
  52. package/dist/operations/planning/apply-plan.d.ts +6 -1
  53. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  54. package/dist/operations/planning/apply-plan.js +8 -2
  55. package/dist/operations/semantic-advisor/clauses.d.ts +9 -0
  56. package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
  57. package/dist/operations/semantic-advisor/clauses.js +24 -0
  58. package/dist/public/operations/catalog.d.ts +14 -5
  59. package/dist/public/operations/catalog.d.ts.map +1 -1
  60. package/dist/public/operations/check-executor.d.ts.map +1 -1
  61. package/dist/public/operations/check-executor.js +3 -0
  62. package/dist/public/operations/contracts.d.ts.map +1 -1
  63. package/dist/public/operations/contracts.js +29 -1
  64. package/dist/public/operations/decision-firmness.d.ts +34 -0
  65. package/dist/public/operations/decision-firmness.d.ts.map +1 -0
  66. package/dist/public/operations/decision-firmness.js +216 -0
  67. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  68. package/dist/public/operations/discovery-executors.js +16 -2
  69. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  70. package/dist/public/operations/migration-plan.js +37 -7
  71. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  72. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  73. package/dist/public/operations/specs/check-rules.generated.js +5 -1
  74. package/dist/public/operations/specs/check.d.ts +1 -1
  75. package/dist/public/operations/specs/mutation-schemas.d.ts +7 -2
  76. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  77. package/dist/public/operations/specs/mutation-schemas.js +13 -17
  78. package/dist/public/operations/specs/mutation.d.ts +6 -2
  79. package/dist/public/operations/specs/mutation.d.ts.map +1 -1
  80. package/dist/public/operations/specs/mutation.js +6 -2
  81. package/dist/public/operations/specs/upsert.d.ts +7 -2
  82. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  83. package/dist/public/schemas/entity.d.ts.map +1 -1
  84. package/dist/public/schemas/entity.js +13 -13
  85. package/dist/public/skills/kibi-traceability/SKILL.md +6 -4
  86. package/dist/public/skills/kibi-usage/SKILL.md +52 -10
  87. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +1 -1
  88. package/dist/public/skills/kibi-usage/resources/source-authoring.md +4 -2
  89. package/dist/public/skills/kibi-usage/resources/ui-requirements.md +2 -2
  90. package/dist/public/skills/kibi-usage/resources/workflows.md +1 -1
  91. package/dist/relationships/shards.d.ts +10 -0
  92. package/dist/relationships/shards.d.ts.map +1 -1
  93. package/dist/relationships/shards.js +27 -11
  94. package/dist/schemas/entity.schema.json +30 -25
  95. package/dist/search-answer.d.ts +31 -2
  96. package/dist/search-answer.d.ts.map +1 -1
  97. package/dist/search-answer.js +115 -17
  98. package/dist/types/entities.d.ts +4 -0
  99. package/dist/types/entities.d.ts.map +1 -1
  100. package/dist/utils/kb-manifest.d.ts +6 -0
  101. package/dist/utils/kb-manifest.d.ts.map +1 -1
  102. package/dist/utils/kb-manifest.js +6 -0
  103. package/dist/utils/rule-registry.generated.d.ts +21 -0
  104. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  105. package/dist/utils/rule-registry.generated.js +25 -0
  106. package/dist/utils/schema-version.d.ts +1 -1
  107. package/dist/utils/schema-version.d.ts.map +1 -1
  108. package/dist/utils/schema-version.js +3 -1
  109. package/package.json +2 -2
  110. package/schema/entities.pl +6 -0
  111. package/src/public/operations/check-executor.ts +6 -0
  112. package/src/public/operations/contracts.ts +33 -1
  113. package/src/public/operations/decision-firmness.ts +280 -0
  114. package/src/public/operations/discovery-executors.ts +17 -2
  115. package/src/public/operations/migration-plan.ts +41 -9
  116. package/src/public/operations/specs/check-rules.generated.ts +5 -1
  117. package/src/public/operations/specs/mutation-schemas.ts +14 -17
  118. package/src/public/operations/specs/mutation.ts +7 -2
  119. package/src/public/schemas/entity.ts +14 -13
  120. package/src/public/skills/kibi-traceability/SKILL.md +6 -4
  121. package/src/public/skills/kibi-usage/SKILL.md +52 -10
  122. package/src/public/skills/kibi-usage/resources/fact-lanes.md +1 -1
  123. package/src/public/skills/kibi-usage/resources/source-authoring.md +4 -2
  124. package/src/public/skills/kibi-usage/resources/ui-requirements.md +2 -2
  125. package/src/public/skills/kibi-usage/resources/workflows.md +1 -1
  126. package/src/schemas/entity.schema.json +30 -25
@@ -197,15 +197,21 @@ export function renderShardWithout(text, selectors, shardPath) {
197
197
  }
198
198
  return document.toString();
199
199
  }
200
- export function removeRelationshipsFromShards(kbRoot, selectors) {
200
+ /**
201
+ * Render every shard that holds a selected relationship without writing it,
202
+ * so a dry run can report the exact bytes a delete would publish.
203
+ */
204
+ // implements REQ-kibi-operation-interface-parity
205
+ export function planRelationshipShardRemovals(kbRoot, selectors) {
201
206
  const wanted = new Set(selectors.map((selector) => `${selector.type}\0${selector.from}\0${selector.to}`));
202
207
  const removed = new Map();
208
+ const bodies = new Map();
203
209
  for (const shardPath of listShards(kbRoot)) {
204
210
  const records = readShard(shardPath);
205
211
  const matching = records.filter((record) => wanted.has(`${record.type}\0${record.from}\0${record.to}`));
206
212
  if (matching.length === 0)
207
213
  continue;
208
- atomicWriteText(shardPath, renderShardWithout(fs.readFileSync(shardPath, "utf8"), selectors, shardPath));
214
+ bodies.set(shardPath, renderShardWithout(fs.readFileSync(shardPath, "utf8"), selectors, shardPath));
209
215
  for (const record of matching) {
210
216
  const key = `${record.type}\0${record.from}\0${record.to}`;
211
217
  const entry = removed.get(key) ?? { paths: [], sources: [] };
@@ -214,15 +220,25 @@ export function removeRelationshipsFromShards(kbRoot, selectors) {
214
220
  removed.set(key, entry);
215
221
  }
216
222
  }
217
- return selectors.map((selector) => {
218
- const entry = removed.get(`${selector.type}\0${selector.from}\0${selector.to}`);
219
- return {
220
- selector,
221
- shardPaths: entry?.paths ?? [],
222
- sources: entry?.sources ?? [],
223
- removed: entry !== undefined,
224
- };
225
- });
223
+ return {
224
+ bodies,
225
+ removals: selectors.map((selector) => {
226
+ const entry = removed.get(`${selector.type}\0${selector.from}\0${selector.to}`);
227
+ return {
228
+ selector,
229
+ shardPaths: entry?.paths ?? [],
230
+ sources: entry?.sources ?? [],
231
+ removed: entry !== undefined,
232
+ };
233
+ }),
234
+ };
235
+ }
236
+ export function removeRelationshipsFromShards(kbRoot, selectors) {
237
+ const planned = planRelationshipShardRemovals(kbRoot, selectors);
238
+ for (const [shardPath, body] of planned.bodies) {
239
+ atomicWriteText(shardPath, body);
240
+ }
241
+ return planned.removals;
226
242
  }
227
243
  /**
228
244
  * Serializes records to YAML format.
@@ -514,6 +514,15 @@
514
514
  },
515
515
  "additionalProperties": false
516
516
  },
517
+ "firmness": {
518
+ "type": "string",
519
+ "enum": [
520
+ "firm",
521
+ "default",
522
+ "exploratory"
523
+ ],
524
+ "description": "Requirement and ADR only. How firmly the decision was made. firm: a human stated it as a rule; it needs a ref (origin.ref, or approval_ref on a requirement) to their words, and only a human may change it. default (assumed when absent): a delegated or agent choice; a later agent may supersede it with evidence. exploratory: a flagged guess, expected to be revisited."
525
+ },
517
526
  "expects": {
518
527
  "type": "string",
519
528
  "enum": [
@@ -1657,6 +1666,25 @@
1657
1666
  }
1658
1667
  }
1659
1668
  },
1669
+ {
1670
+ "if": {
1671
+ "properties": {
1672
+ "type": {
1673
+ "enum": [
1674
+ "req",
1675
+ "adr"
1676
+ ]
1677
+ }
1678
+ }
1679
+ },
1680
+ "else": {
1681
+ "not": {
1682
+ "required": [
1683
+ "firmness"
1684
+ ]
1685
+ }
1686
+ }
1687
+ },
1660
1688
  {
1661
1689
  "if": {
1662
1690
  "properties": {
@@ -1675,35 +1703,12 @@
1675
1703
  },
1676
1704
  {
1677
1705
  "if": {
1678
- "anyOf": [
1679
- {
1680
- "required": [
1681
- "claim_key"
1682
- ]
1683
- },
1684
- {
1685
- "required": [
1686
- "claim_text"
1687
- ],
1688
- "not": {
1689
- "properties": {
1690
- "fact_kind": {
1691
- "enum": [
1692
- "observation",
1693
- "meta"
1694
- ]
1695
- }
1696
- },
1697
- "required": [
1698
- "fact_kind"
1699
- ]
1700
- }
1701
- }
1706
+ "required": [
1707
+ "claim_key"
1702
1708
  ]
1703
1709
  },
1704
1710
  "then": {
1705
1711
  "required": [
1706
- "claim_key",
1707
1712
  "claim_text"
1708
1713
  ]
1709
1714
  }
@@ -1,3 +1,4 @@
1
+ import { type Firmness } from "./decision-firmness.js";
1
2
  import type { IntentSearchMatch } from "./intent-search.js";
2
3
  import type { PrologPort } from "./public/operations/runtime-types.js";
3
4
  /**
@@ -19,6 +20,12 @@ export type SearchAnswerEntity = Readonly<{
19
20
  id: string;
20
21
  title: string;
21
22
  status?: string;
23
+ /**
24
+ * Requirements and ADRs: how firmly the decision was made. `firm` (a human
25
+ * stated it; ask before changing), `default` (supersede it with evidence),
26
+ * `exploratory` (a guess to revisit).
27
+ */
28
+ firmness?: Firmness;
22
29
  }>;
23
30
  /**
24
31
  * A test verifying a governing requirement. `via` is `"direct"` for a test
@@ -69,8 +76,13 @@ export type SearchAnswerException = SearchAnswerEntity & Readonly<{
69
76
  /**
70
77
  * A linked fact says what it states in its typed form, so an agent can read
71
78
  * `has_role(alice, admin)` or `user.role_assignment max_roles lte 2` without
72
- * opening the entity, and `ask` is the exact kb_query that answers precise
73
- * questions about the same predicate or subject.
79
+ * opening the entity, and `ask` is the kb_query that reproduces the fact's
80
+ * own tuple as precisely as kb_query supports: a property or subject fact by
81
+ * its keys; a predicate fact by name plus, when a project `predicate_schema`
82
+ * or the built-in signature declares its arguments, `where` over the key
83
+ * arguments (the declared `key_arguments`, else the argument named `subject`,
84
+ * else the first), otherwise its full positional `args`. Pasted, it returns
85
+ * the fact and only facts sharing those key arguments.
74
86
  */
75
87
  export type SearchAnswerFact = SearchAnswerEntity & Readonly<{
76
88
  factKind?: string;
@@ -142,6 +154,23 @@ export declare const SEARCH_ANSWER_LIMITS: {
142
154
  /** Characters of a witness or unknown detail kept. */
143
155
  readonly detailChars: 240;
144
156
  };
157
+ /**
158
+ * The declared arguments of a predicate fact's schema: a project
159
+ * `predicate_schema` or the built-in signature kb_query resolves `where`
160
+ * names against. `keyArguments` is empty when the schema declares none.
161
+ */
162
+ export type PredicateFactSchema = Readonly<{
163
+ argumentNames: readonly string[];
164
+ keyArguments: readonly string[];
165
+ }>;
166
+ /**
167
+ * The `where` filter that selects the facts sharing a predicate fact's key
168
+ * arguments: the schema's `key_arguments`, else the argument named `subject`,
169
+ * else the first argument. Undefined when the schema does not fit the fact
170
+ * (arity) or no key argument has a value, so the caller falls back to
171
+ * positional args.
172
+ */
173
+ export declare function predicateKeyFilter(args: readonly string[], schema: PredicateFactSchema): Record<string, string> | undefined;
145
174
  /**
146
175
  * The opening sentences of an ADR's Decision section (falling back to
147
176
  * Rationale, then to the first prose paragraph), as plain text of at most
@@ -1 +1 @@
1
- {"version":3,"file":"search-answer.d.ts","sourceRoot":"","sources":["../src/search-answer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-answer.d.ts","sourceRoot":"","sources":["../src/search-answer.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { escapeAtom, normalizeEntityId, parseEntityFromList, parseListOfLists, parseTriples, } from "./prolog/codec.js";
1
+ import { effectiveFirmness } from "./decision-firmness.js";
2
+ import { escapeAtom, normalizeEntityId, parseAtomList, parseEntityFromList, parseListOfLists, parseTriples, } from "./prolog/codec.js";
2
3
  import { isProvenanceStub } from "./provenance-stub.js";
3
4
  import { entityRowsGoal } from "./public/operations/discovery-entities.js";
4
5
  import { runOperationJsonQuery } from "./public/operations/prolog-json.js";
@@ -41,6 +42,7 @@ const ROW_KEYS = [
41
42
  "status",
42
43
  "fact_kind",
43
44
  "approved_by",
45
+ "firmness",
44
46
  "source",
45
47
  "sourceFile",
46
48
  "predicate_namespace",
@@ -84,30 +86,68 @@ function unique(ids) {
84
86
  }
85
87
  function brief(entity) {
86
88
  const status = text(entity.status);
89
+ const firmness = effectiveFirmness(entity.type, entity.firmness);
87
90
  return {
88
91
  id: text(entity.id),
89
92
  title: text(entity.title),
90
93
  ...(status ? { status } : {}),
94
+ ...(firmness ? { firmness } : {}),
91
95
  };
92
96
  }
93
97
  function queryCall(args) {
94
98
  return `kb_query(${JSON.stringify(args)})`;
95
99
  }
100
+ /**
101
+ * The `where` filter that selects the facts sharing a predicate fact's key
102
+ * arguments: the schema's `key_arguments`, else the argument named `subject`,
103
+ * else the first argument. Undefined when the schema does not fit the fact
104
+ * (arity) or no key argument has a value, so the caller falls back to
105
+ * positional args.
106
+ */
107
+ // implements REQ-kibi-query-fact-filters
108
+ export function predicateKeyFilter(args, schema) {
109
+ const names = schema.argumentNames;
110
+ if (names.length === 0 || names.length !== args.length)
111
+ return undefined;
112
+ const declared = schema.keyArguments.filter((key) => names.includes(key));
113
+ const keys = declared.length > 0
114
+ ? declared
115
+ : [names.includes("subject") ? "subject" : names[0]];
116
+ const where = {};
117
+ for (const key of keys) {
118
+ const value = args[names.indexOf(key)] ?? "";
119
+ if (value !== "")
120
+ where[key] = value;
121
+ }
122
+ return Object.keys(where).length > 0 ? where : undefined;
123
+ }
96
124
  /** Typed statement and follow-up query of a linked fact, by fact kind. */
97
125
  // implements REQ-kibi-query-fact-filters
98
- function factDetail(fact) {
126
+ function factDetail(fact, schema) {
99
127
  const factKind = text(fact.fact_kind);
100
128
  const base = factKind ? { factKind } : {};
101
129
  const predicate = text(fact.predicate_name);
102
130
  if (factKind === "predicate" && predicate) {
103
131
  const args = Array.isArray(fact.predicate_args)
104
- ? fact.predicate_args.map(text).join(", ")
105
- : text(fact.predicate_args);
132
+ ? fact.predicate_args.map(text)
133
+ : undefined;
106
134
  const polarity = text(fact.polarity) === "deny" ? " [deny]" : "";
135
+ const namespace = text(fact.predicate_namespace);
136
+ const call = {
137
+ predicate,
138
+ ...(namespace && namespace !== "default" ? { namespace } : {}),
139
+ };
140
+ if (args !== undefined && args.length > 0) {
141
+ const where = schema ? predicateKeyFilter(args, schema) : undefined;
142
+ if (where)
143
+ call.where = where;
144
+ else
145
+ call.args = args.map((value) => (value === "" ? null : value));
146
+ }
107
147
  return {
108
148
  ...base,
109
- claim: `${predicate}(${args})${polarity}`,
110
- ask: queryCall({ predicate }),
149
+ claim: `${predicate}(${args?.join(", ") ?? text(fact.predicate_args)})${polarity}`,
150
+ ask: queryCall(call),
111
151
  };
112
152
  }
113
153
  const subjectKey = text(fact.subject_key);
@@ -128,6 +168,27 @@ function edgesGoal(ids) {
128
168
  const idList = ids.map((id) => `'${escapeAtom(id)}'`).join(",");
129
169
  return `findall([Rel,From,To], (member(Rel, [${ANSWER_RELATIONSHIPS.join(",")}]), kb_relationship(Rel, From, To), (member(From, [${idList}]); member(To, [${idList}]))), Edges)`;
130
170
  }
171
+ /**
172
+ * For each predicate fact among `ids`, the argument names and key arguments
173
+ * of the schema kb_query resolves its `where` names against: the project
174
+ * `predicate_schema` of its namespace and name, else the built-in signature.
175
+ * Facts of other kinds, and predicates without a schema, yield no row.
176
+ */
177
+ // implements REQ-kibi-query-fact-filters
178
+ function factSchemasGoal(ids) {
179
+ const idList = ids.map((id) => `'${escapeAtom(id)}'`).join(",");
180
+ return `findall([FactId,Names,Keys], (member(FactId, [${idList}]), kb:predicate_fact(FactId, Ns, Name, _, _), ((kb:predicate_schema(SchemaId, Ns, Name, _, Names, _) -> ((kb_entity(SchemaId, fact, Props), memberchk(key_arguments=KeysRaw, Props), kb:normalize_term_atom_list(KeysRaw, Keys)) -> true ; Keys = [])) ; (kb:builtin_decision_predicate(Ns, Name, _, KeyPositions, _), kb:builtin_predicate_signature(Name, _, Names), findall(Key, (member(P, KeyPositions), nth1(P, Names, Key)), Keys)))), Schemas)`;
181
+ }
182
+ function parseFactSchemas(raw) {
183
+ const schemas = new Map();
184
+ for (const [id, names, keys] of parseTriples(raw ?? "[]")) {
185
+ schemas.set(normalizeEntityId(id), {
186
+ argumentNames: parseAtomList(names),
187
+ keyArguments: parseAtomList(keys),
188
+ });
189
+ }
190
+ return schemas;
191
+ }
131
192
  /**
132
193
  * The part of the KB graph the answer reads, fetched in batches: each
133
194
  * `fetch` is one engine round trip for every id whose edges or row are not
@@ -489,6 +550,29 @@ async function fetchVerdicts(prolog, graph, rowIds, reqIds) {
489
550
  return undefined;
490
551
  }
491
552
  }
553
+ /**
554
+ * The rows the answer still needs plus the schemas of the predicate facts
555
+ * among `factIds`, in one round trip. A schema lookup the engine cannot run
556
+ * leaves the rows loaded and every ask positional.
557
+ */
558
+ // implements REQ-kibi-query-fact-filters
559
+ async function fetchFactSchemas(graph, factIds, request) {
560
+ if (factIds.length === 0) {
561
+ await graph.fetch(request);
562
+ return new Map();
563
+ }
564
+ try {
565
+ const bindings = await graph.fetch({
566
+ ...request,
567
+ alsoGoal: factSchemasGoal(factIds),
568
+ });
569
+ return parseFactSchemas(bindings.Schemas);
570
+ }
571
+ catch {
572
+ await graph.fetch(request);
573
+ return new Map();
574
+ }
575
+ }
492
576
  // implements REQ-bootstrap-provenance-stubs
493
577
  export async function buildSearchAnswer(prolog, matches, options = {}) {
494
578
  const limits = SEARCH_ANSWER_LIMITS;
@@ -551,13 +635,9 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
551
635
  continue;
552
636
  }
553
637
  if (owners.length === 0 && ["fact", "scenario", "symbol"].includes(type)) {
638
+ // A fact's claim and ask are filled in once its schema is known.
554
639
  if (ungoverned.length < limits.ungoverned)
555
- ungoverned.push({
556
- ...brief(entity),
557
- ...(type === "fact" ? factDetail(entity) : {}),
558
- type,
559
- rank: index + 1,
560
- });
640
+ ungoverned.push({ ...brief(entity), type, rank: index + 1 });
561
641
  else
562
642
  truncated = true;
563
643
  continue;
@@ -689,7 +769,13 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
689
769
  exceptions: firstOf(into("exempts")),
690
770
  };
691
771
  });
692
- await graph.fetch({
772
+ // The schemas of the linked and ungoverned predicate facts share this
773
+ // round trip, so each fact's ask can name its key arguments.
774
+ const factIds = unique([
775
+ ...ungoverned.filter((entry) => entry.type === "fact").map((e) => e.id),
776
+ ...plans.flatMap((plan) => plan.facts),
777
+ ]);
778
+ const schemas = await fetchFactSchemas(graph, factIds, {
693
779
  edges: plans.flatMap((plan) => plan.scenarios),
694
780
  rows: plans.flatMap((plan) => [
695
781
  ...plan.facts,
@@ -699,6 +785,18 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
699
785
  ...plan.directTests.slice(0, limits.perRequirement),
700
786
  ]),
701
787
  });
788
+ const detailedUngoverned = ungoverned.map((entry) => {
789
+ const row = entry.type === "fact" ? graph.row(entry.id) : null;
790
+ if (row === null)
791
+ return entry;
792
+ const { type, rank } = entry;
793
+ return {
794
+ ...brief(row),
795
+ ...factDetail(row, schemas.get(entry.id)),
796
+ type,
797
+ rank,
798
+ };
799
+ });
702
800
  // Tests linked to the requirement itself come first, then tests that
703
801
  // verify one of its scenarios; a test reached both ways counts as direct.
704
802
  const testVias = plans.map((plan) => {
@@ -738,7 +836,7 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
738
836
  via: req.via,
739
837
  facts: rowsOf(plan.facts).map((fact) => ({
740
838
  ...brief(fact),
741
- ...factDetail(fact),
839
+ ...factDetail(fact, schemas.get(text(fact.id))),
742
840
  })),
743
841
  scenarios: rowsOf(plan.scenarios).map(brief),
744
842
  tests: rowsOf(testIds[index] ?? []).map((row) => ({
@@ -769,17 +867,17 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
769
867
  ? verdicts.scope.syncedAt
770
868
  : null,
771
869
  };
772
- ungoverned.sort((left, right) => left.rank - right.rank);
870
+ detailedUngoverned.sort((left, right) => left.rank - right.rank);
773
871
  const answer = {
774
872
  version: "kibi.search-answer.v1",
775
873
  governing,
776
874
  rationale,
777
875
  notGoverning,
778
876
  observations: observations.slice(0, limits.observations),
779
- ungoverned,
877
+ ungoverned: detailedUngoverned,
780
878
  scope,
781
879
  truncated: truncated || graph.truncated,
782
- note: answerNote(governing.length, ungoverned),
880
+ note: answerNote(governing.length, detailedUngoverned),
783
881
  };
784
882
  return fitSearchAnswer(answer, limits.maxBytes);
785
883
  }
@@ -67,6 +67,8 @@ export type Requirement = BaseEntity & {
67
67
  approval_ref?: string;
68
68
  /** Why the requirement exists; explanation, not checked meaning. */
69
69
  rationale?: string;
70
+ /** How firmly it was decided; absent reads as default. */
71
+ firmness?: "firm" | "default" | "exploratory";
70
72
  /** Exception requirements only: claim keys of the exempted requirement it waives. */
71
73
  exempts_claims?: string[];
72
74
  };
@@ -78,6 +80,8 @@ export type TestEntity = BaseEntity & TestVerificationFields & {
78
80
  };
79
81
  export type ADR = BaseEntity & {
80
82
  type: "adr";
83
+ /** How firmly it was decided; absent reads as default. */
84
+ firmness?: "firm" | "default" | "exploratory";
81
85
  };
82
86
  export type Flag = BaseEntity & {
83
87
  type: "flag";
@@ -1 +1 @@
1
- {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/types/entities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/types/entities.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,12 @@ export interface KbManifest {
20
20
  * Only these ids may carry `review:context-missing` without a violation.
21
21
  */
22
22
  contextAcknowledged?: string[];
23
+ /**
24
+ * Supersede edges (`FROM -> TO`) the schema 9 migration acknowledged as
25
+ * lacking a "Why this changed" section. An entity is exempt from
26
+ * supersedes-reason-missing only while every edge it has is listed here.
27
+ */
28
+ supersedesReasonAcknowledged?: string[];
23
29
  }
24
30
  export declare function defaultKbManifest(): KbManifest;
25
31
  export type KbManifestStatus = {
@@ -1 +1 @@
1
- {"version":3,"file":"kb-manifest.d.ts","sourceRoot":"","sources":["../../src/utils/kb-manifest.ts"],"names":[],"mappings":"AA8BA;;;;;;;GAOG;AAEH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,MAAM,MAAM,uBAAuB,GAC/B,SAAS,GACT,WAAW,GACX,gBAAgB,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,eAAe,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,aAAa,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,uBAAuB,EAAE,uBAAuB,CAAC;IACjD;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,wBAAgB,iBAAiB,IAAI,UAAU,CAM9C;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAClE;IACE,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACxC,QAAQ,EAAE,IAAI,CAAC;IACf,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAuDN,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,gBAAgB,CAyD5E;AAED,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAGvE;AAED,8EAA8E;AAC9E,wBAAgB,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,CAEzE;AASD,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,UAAU,GACnB,MAAM,CAIR"}
1
+ {"version":3,"file":"kb-manifest.d.ts","sourceRoot":"","sources":["../../src/utils/kb-manifest.ts"],"names":[],"mappings":"AA8BA;;;;;;;GAOG;AAEH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,MAAM,MAAM,uBAAuB,GAC/B,SAAS,GACT,WAAW,GACX,gBAAgB,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,eAAe,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,aAAa,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,uBAAuB,EAAE,uBAAuB,CAAC;IACjD;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B;;;;OAIG;IACH,4BAA4B,CAAC,EAAE,MAAM,EAAE,CAAC;CACzC;AAED,wBAAgB,iBAAiB,IAAI,UAAU,CAM9C;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAClE;IACE,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACxC,QAAQ,EAAE,IAAI,CAAC;IACf,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AA+DN,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,gBAAgB,CAyD5E;AAED,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAGvE;AAED,8EAA8E;AAC9E,wBAAgB,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,CAEzE;AASD,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,UAAU,GACnB,MAAM,CAIR"}
@@ -71,6 +71,7 @@ function validateManifest(parsed) {
71
71
  return null;
72
72
  }
73
73
  const acknowledged = parsed.contextAcknowledged;
74
+ const supersedesAcknowledged = parsed.supersedesReasonAcknowledged;
74
75
  return {
75
76
  manifestVersion,
76
77
  schemaVersion,
@@ -80,6 +81,11 @@ function validateManifest(parsed) {
80
81
  contextAcknowledged: acknowledged.filter((id) => typeof id === "string"),
81
82
  }
82
83
  : {}),
84
+ ...(Array.isArray(supersedesAcknowledged)
85
+ ? {
86
+ supersedesReasonAcknowledged: supersedesAcknowledged.filter((id) => typeof id === "string"),
87
+ }
88
+ : {}),
83
89
  };
84
90
  }
85
91
  export function readKbManifestStatus(workspaceRoot) {
@@ -228,6 +228,27 @@ export declare const GENERATED_RULES: readonly [{
228
228
  readonly enforcementClass: "advisory";
229
229
  readonly category: "lifecycle";
230
230
  readonly diagnosticSeverity: "info";
231
+ }, {
232
+ readonly name: "decision-firm-unreferenced";
233
+ readonly description: "A requirement or ADR marked firmness: firm must name the human words it rests on: origin.ref (or approval_ref on a requirement); Kibi checks that the reference is present, not that it is genuine";
234
+ readonly enforcementClass: "canonical";
235
+ readonly category: "integrity";
236
+ }, {
237
+ readonly name: "decision-firm-superseded";
238
+ readonly description: "A requirement or ADR that supersedes a firm decision, retired or not, must itself be firm (and so carry a ref to the human who changed the rule); a default or exploratory replacement cannot overrule a firm decision";
239
+ readonly enforcementClass: "canonical";
240
+ readonly category: "lifecycle";
241
+ }, {
242
+ readonly name: "supersedes-reason-missing";
243
+ readonly description: "A current requirement or ADR that supersedes another must explain why under a 'Why this changed' heading (at least 12 words of prose naming the evidence and answering the old decision's reasoning); supersede edges recorded before schema 9 are acknowledged in the manifest and exempt";
244
+ readonly enforcementClass: "canonical";
245
+ readonly category: "lifecycle";
246
+ }, {
247
+ readonly name: "supersedes-reason-acknowledged";
248
+ readonly description: "Informational: how many current superseding requirements and ADRs have only supersede edges the schema 9 migration acknowledged without a 'Why this changed' section; one summary finding per check";
249
+ readonly enforcementClass: "advisory";
250
+ readonly category: "lifecycle";
251
+ readonly diagnosticSeverity: "info";
231
252
  }, {
232
253
  readonly name: "policy-ownership";
233
254
  readonly description: "When a plugin activated for kibi.check-policy.v1 declares ownership rules, every production symbol in a rule's file set must implement a current requirement grounded (requires_predicate) in one of the rule's predicates; projects without an activated check policy are unaffected";
@@ -1 +1 @@
1
- {"version":3,"file":"rule-registry.generated.d.ts","sourceRoot":"","sources":["../../src/utils/rule-registry.generated.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4UlB,CAAC"}
1
+ {"version":3,"file":"rule-registry.generated.d.ts","sourceRoot":"","sources":["../../src/utils/rule-registry.generated.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyWlB,CAAC"}
@@ -283,6 +283,31 @@ export const GENERATED_RULES = [
283
283
  category: "lifecycle",
284
284
  diagnosticSeverity: "info",
285
285
  },
286
+ {
287
+ name: "decision-firm-unreferenced",
288
+ description: "A requirement or ADR marked firmness: firm must name the human words it rests on: origin.ref (or approval_ref on a requirement); Kibi checks that the reference is present, not that it is genuine",
289
+ enforcementClass: "canonical",
290
+ category: "integrity",
291
+ },
292
+ {
293
+ name: "decision-firm-superseded",
294
+ description: "A requirement or ADR that supersedes a firm decision, retired or not, must itself be firm (and so carry a ref to the human who changed the rule); a default or exploratory replacement cannot overrule a firm decision",
295
+ enforcementClass: "canonical",
296
+ category: "lifecycle",
297
+ },
298
+ {
299
+ name: "supersedes-reason-missing",
300
+ description: "A current requirement or ADR that supersedes another must explain why under a 'Why this changed' heading (at least 12 words of prose naming the evidence and answering the old decision's reasoning); supersede edges recorded before schema 9 are acknowledged in the manifest and exempt",
301
+ enforcementClass: "canonical",
302
+ category: "lifecycle",
303
+ },
304
+ {
305
+ name: "supersedes-reason-acknowledged",
306
+ description: "Informational: how many current superseding requirements and ADRs have only supersede edges the schema 9 migration acknowledged without a 'Why this changed' section; one summary finding per check",
307
+ enforcementClass: "advisory",
308
+ category: "lifecycle",
309
+ diagnosticSeverity: "info",
310
+ },
286
311
  {
287
312
  name: "policy-ownership",
288
313
  description: "When a plugin activated for kibi.check-policy.v1 declares ownership rules, every production symbol in a rule's file set must implement a current requirement grounded (requires_predicate) in one of the rule's predicates; projects without an activated check policy are unaffected",
@@ -1,4 +1,4 @@
1
- export declare const LATEST_KB_SCHEMA_VERSION = 8;
1
+ export declare const LATEST_KB_SCHEMA_VERSION = 9;
2
2
  export interface SchemaVersionStatus {
3
3
  status: "missing" | "invalid" | "older" | "current" | "newer";
4
4
  currentVersion: number | null;
@@ -1 +1 @@
1
- {"version":3,"file":"schema-version.d.ts","sourceRoot":"","sources":["../../src/utils/schema-version.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;IAC9D,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CAAE,GACrD,IAAI,GACJ,SAAS,CAAC;AAGd,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAChD,MAAM,GAAG,IAAI,CAgBf;AAGD,wBAAgB,sBAAsB,CACpC,MAAM,CAAC,EAAE,mBAAmB,GAC3B,mBAAmB,CAgDrB"}
1
+ {"version":3,"file":"schema-version.d.ts","sourceRoot":"","sources":["../../src/utils/schema-version.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;IAC9D,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CAAE,GACrD,IAAI,GACJ,SAAS,CAAC;AAGd,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAChD,MAAM,GAAG,IAAI,CAgBf;AAGD,wBAAgB,sBAAsB,CACpC,MAAM,CAAC,EAAE,mBAAmB,GAC3B,mBAAmB,CAgDrB"}
@@ -18,7 +18,9 @@
18
18
  // implements REQ-003
19
19
  // Schema 8 requires body context on current entities and pins requirement
20
20
  // semantic_text so context sections never change a requirement's meaning.
21
- export const LATEST_KB_SCHEMA_VERSION = 8;
21
+ // Schema 9 adds decision firmness on requirements and ADRs and requires a
22
+ // "Why this changed" section on new supersedes.
23
+ export const LATEST_KB_SCHEMA_VERSION = 9;
22
24
  // implements REQ-003
23
25
  export function normalizeSchemaVersion(schemaVersion) {
24
26
  if (schemaVersion === undefined || schemaVersion === null) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-cli",
3
- "version": "2.20.0",
3
+ "version": "2.21.2",
4
4
  "type": "module",
5
5
  "description": "Kibi CLI for knowledge base management",
6
6
  "engines": {
@@ -235,7 +235,7 @@
235
235
  "fast-glob": "^3.2.12",
236
236
  "gray-matter": "^4.0.3",
237
237
  "js-yaml": "^4.1.0",
238
- "kibi-core": "^0.21.0",
238
+ "kibi-core": "^0.21.1",
239
239
  "kibi-plugin-builtin": "^0.5.1",
240
240
  "kibi-plugin-sdk": "^0.5.0",
241
241
  "kibi-swipl": "^1.0.1",
@@ -51,6 +51,10 @@ entity_property(req, approval_ref, string).
51
51
  entity_property(req, rationale, string).
52
52
  % Claim keys of the exempted requirement an exception waives (all when absent).
53
53
  entity_property(req, exempts_claims, list).
54
+ % How firmly a requirement or ADR was decided: firm, default or exploratory.
55
+ % Absent reads as default.
56
+ entity_property(req, firmness, atom).
57
+ entity_property(adr, firmness, atom).
54
58
  % Intended outcome of a scenario: success, rejection or error.
55
59
  entity_property(scenario, expects, atom).
56
60
 
@@ -143,6 +147,8 @@ optional_property(req, approved_by).
143
147
  optional_property(req, approval_ref).
144
148
  optional_property(req, rationale).
145
149
  optional_property(req, exempts_claims).
150
+ optional_property(req, firmness).
151
+ optional_property(adr, firmness).
146
152
  optional_property(test, verification_scope).
147
153
  optional_property(test, verification_perspective).
148
154
  optional_property(test, proof_contract).