kibi-cli 2.21.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.
- package/dist/cli-operation-metadata.d.ts +1 -1
- package/dist/cli-operation-metadata.js +1 -1
- package/dist/commands/doctor.js +13 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +15 -3
- package/dist/commands/legacy-storage-migration.d.ts.map +1 -1
- package/dist/commands/legacy-storage-migration.js +26 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +123 -5
- 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/operations/migration/schema6.d.ts +2 -0
- package/dist/operations/migration/schema6.d.ts.map +1 -1
- package/dist/operations/migration/schema6.js +44 -1
- 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/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/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/types.d.ts +37 -0
- package/dist/operations/mutation/types.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +54 -2
- 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 +8 -2
- package/dist/public/operations/catalog.d.ts +12 -3
- 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/contracts.d.ts.map +1 -1
- package/dist/public/operations/contracts.js +29 -1
- 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.map +1 -1
- package/dist/public/operations/discovery-executors.js +16 -2
- package/dist/public/operations/migration-plan.js +1 -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 +5 -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/upsert.d.ts +5 -0
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- 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/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/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 +21 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +25 -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 +2 -2
- package/schema/entities.pl +6 -0
- package/src/public/operations/check-executor.ts +6 -0
- package/src/public/operations/contracts.ts +33 -1
- package/src/public/operations/decision-firmness.ts +280 -0
- package/src/public/operations/discovery-executors.ts +17 -2
- package/src/public/operations/migration-plan.ts +1 -1
- package/src/public/operations/specs/check-rules.generated.ts +5 -1
- package/src/public/operations/specs/mutation-schemas.ts +6 -0
- package/src/public/operations/specs/mutation.ts +7 -2
- 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/schemas/entity.schema.json +28 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../../src/public/schemas/entity.ts"],"names":[],"mappings":"AAwTA,QAAA,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../../src/public/schemas/entity.ts"],"names":[],"mappings":"AAwTA,QAAA,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAwazC,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -333,6 +333,11 @@ const entitySchema = {
|
|
|
333
333
|
text_ref: { type: "string" },
|
|
334
334
|
// Provenance of any authored entity: who wrote it and on what authority.
|
|
335
335
|
origin: ENTITY_ORIGIN_SCHEMA,
|
|
336
|
+
firmness: {
|
|
337
|
+
type: "string",
|
|
338
|
+
enum: ["firm", "default", "exploratory"],
|
|
339
|
+
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.",
|
|
340
|
+
},
|
|
336
341
|
expects: {
|
|
337
342
|
type: "string",
|
|
338
343
|
enum: ["success", "rejection", "error"],
|
|
@@ -680,6 +685,12 @@ const entitySchema = {
|
|
|
680
685
|
},
|
|
681
686
|
},
|
|
682
687
|
},
|
|
688
|
+
{
|
|
689
|
+
if: {
|
|
690
|
+
properties: { type: { enum: ["req", "adr"] } },
|
|
691
|
+
},
|
|
692
|
+
else: { not: { required: ["firmness"] } },
|
|
693
|
+
},
|
|
683
694
|
{
|
|
684
695
|
if: {
|
|
685
696
|
properties: { type: { const: "scenario" } },
|
|
@@ -43,10 +43,12 @@ sequential `kb_upsert`, then run final check and coverage. Kibi authors tracked
|
|
|
43
43
|
files transactionally but never Git-stages or commits them. Do not read or edit
|
|
44
44
|
`.kb` directly.
|
|
45
45
|
|
|
46
|
-
Use `kb_delete` only for intentional cleanup
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
Use `kb_delete` only for intentional cleanup; `dryRun: true` previews any
|
|
47
|
+
delete without writing. Authored entity deletion returns `outcome:
|
|
48
|
+
plan_returned` with a hash-bound plan whose `nextActions[0].input` is the exact
|
|
49
|
+
`kb_apply_plan` input; requirements return `supersession_required` and evolve
|
|
50
|
+
through a new requirement linked with `supersedes`. Relationship deletes patch
|
|
51
|
+
shards while preserving unrelated records.
|
|
50
52
|
|
|
51
53
|
## Typed recovery and proof
|
|
52
54
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-usage
|
|
3
3
|
name: Kibi Usage
|
|
4
4
|
description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
|
|
5
|
-
version: 2.
|
|
5
|
+
version: 2.16.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -188,8 +188,9 @@ returns `status: error`, `MIGRATION_PLAN_REFUSED` and `data.outcome:
|
|
|
188
188
|
refused`: nothing changed, so read the action `detail` and get a new plan.
|
|
189
189
|
`data.outcome: reconciliation_required` (status success) means an action
|
|
190
190
|
failed mid-way: inspect its effect before retrying. `kb_delete` of an
|
|
191
|
-
authored entity returns status success with `deleted: 0
|
|
192
|
-
|
|
191
|
+
authored entity returns status success with `deleted: 0` and `outcome:
|
|
192
|
+
plan_returned` (or `supersession_required` for a requirement): nothing was
|
|
193
|
+
deleted yet, and `nextActions` names the call that does it. If the status is
|
|
193
194
|
`committed_with_repairs`, the mutation already committed: inspect failed effects,
|
|
194
195
|
execute each required repair action in order, and never retry the original
|
|
195
196
|
operation. Record effect failures, followed actions, and unsafe retries in
|
|
@@ -302,12 +303,18 @@ authored. Each one is the order the write path accepts.
|
|
|
302
303
|
between the two writes `kb_check` reports the requirement until the
|
|
303
304
|
second lands.
|
|
304
305
|
3. **Deleting authored entities.** `kb_delete` on an authored entity that
|
|
305
|
-
is not a requirement (scenario, test, fact, ADR, …)
|
|
306
|
-
`
|
|
307
|
-
`
|
|
308
|
-
|
|
309
|
-
`
|
|
310
|
-
|
|
306
|
+
is not a requirement (scenario, test, fact, ADR, …) writes nothing and
|
|
307
|
+
returns `outcome: plan_returned` with a hash-bound
|
|
308
|
+
`kibi.entity-deletion-plan.v1` in `deletionPlan`. After review, run
|
|
309
|
+
`nextActions[0]` unchanged: `kb_apply_plan` with its `input` (`plan` plus
|
|
310
|
+
`approvedPlanHash: plan.planHash`), or repeat the `kb_delete` call with
|
|
311
|
+
`approvedPlanHash` to apply the freshly computed plan in one step (a
|
|
312
|
+
changed source fails with `DELETE_PLAN_HASH_MISMATCH`). `dryRun: true`
|
|
313
|
+
previews relationship and direct deletes without writing. For an
|
|
314
|
+
authored requirement the result is `outcome: supersession_required`, the
|
|
315
|
+
plan carries `supersessionRequired: true` and both routes refuse it
|
|
316
|
+
(`REQUIREMENT_SUPERSESSION_REQUIRED`): Kibi never deletes an authored
|
|
317
|
+
requirement. Evolve it instead with a new
|
|
311
318
|
requirement linked by `supersedes` and close the old one, or, for an
|
|
312
319
|
agent-origin requirement nobody approved and nothing links to, upsert it
|
|
313
320
|
with `status: closed` (keep its `title`); it stays on disk as history. A
|
|
@@ -342,6 +349,29 @@ human sets `approved_by`; `kb_check` flags approvals an agent recorded without
|
|
|
342
349
|
corroboration. Never fill in an approval yourself. Record why a requirement
|
|
343
350
|
exists in `rationale`, or link the ADR that explains it.
|
|
344
351
|
|
|
352
|
+
## Decision firmness
|
|
353
|
+
|
|
354
|
+
Requirements and ADRs carry `firmness`, which says what you may do with them.
|
|
355
|
+
Search answers, `kb_query` rows and hook snippets show it (snippets label only
|
|
356
|
+
`[firm]` and `[exploratory]`; an unlabeled decision is `default`).
|
|
357
|
+
|
|
358
|
+
- `firm`: a human stated it as a rule. Follow it; to change it, ask first.
|
|
359
|
+
`kb_check` blocks a firm decision without `origin.ref` to their words, and
|
|
360
|
+
a replacement of a firm decision that is not itself firm.
|
|
361
|
+
- `default` (when absent): a delegated or agent choice. Follow it unless the
|
|
362
|
+
task gives evidence against it; then supersede it in the same change and
|
|
363
|
+
list it under "Decisions I changed" for review, without asking first.
|
|
364
|
+
- `exploratory`: a flagged guess; revisit it when you touch the area.
|
|
365
|
+
|
|
366
|
+
Set `firmness` from what a human actually said: only their stated rule is
|
|
367
|
+
`firm` (with `origin.ref`); "do whatever" or your own pick is `default`; a
|
|
368
|
+
guess is `exploratory`. A supersede needs `## Why this changed` in the new
|
|
369
|
+
entity's body (at least 12 words): name the evidence (a failing test, a
|
|
370
|
+
measured cost, a constraint the old decision missed, a new requirement) and
|
|
371
|
+
answer the old decision's reasoning; `kb_check` blocks it otherwise. A
|
|
372
|
+
preference is not evidence: propose it instead of superseding. Kibi checks
|
|
373
|
+
only that a firm decision has a reference; never cite words nobody said.
|
|
374
|
+
|
|
345
375
|
Conditional clauses ("only when", "only if", "must not ... unless") compile
|
|
346
376
|
into typed `forbid` rules linked by `requires_rule`, not property facts; one
|
|
347
377
|
`kb_model` or `kb_compile_intent` cannot translate stays an `ontology_gap`.
|
|
@@ -421,7 +451,17 @@ a second grounding link would fail, so keep the existing link or apply the
|
|
|
421
451
|
`kb_delete` of the old link, requirement link; between the last two `kb_check`
|
|
422
452
|
reports both `logic-coverage` and `strict-req-fact-pairing` for the
|
|
423
453
|
requirement, as `expected.kbCheckAfterStep` states; run `kb_check` after the
|
|
424
|
-
last step and apply `rollback` if it is not clean)
|
|
454
|
+
last step and apply `rollback` if it is not clean). `keep_existing_grounding`
|
|
455
|
+
means the requirement already links a predicate fact with the candidate's
|
|
456
|
+
`canonical_key` (`existingGrounding[].matchedBy` is `canonical_key` when the
|
|
457
|
+
claim was worded differently), so write nothing. `extend_requirement` means
|
|
458
|
+
the requirement's proposition ledger has no entry for this text, so a link
|
|
459
|
+
cannot be made and no fact is planned: add the clause to the requirement's
|
|
460
|
+
prose (`mode: "requirement"`, or `kb_upsert` with the extended `semantic_text`
|
|
461
|
+
and the ledger `mode: "analyze"` returns) and call `mode: "predicates"` again.
|
|
462
|
+
Read `decisionConflicts` and its warnings whenever `plan` is null: they name
|
|
463
|
+
the stored decision facts the candidate would contradict and the requirements
|
|
464
|
+
that own them. `provide_argument_bindings` and `record_ontology_gap` mean
|
|
425
465
|
the same as for an ungrounded claim, and the gap observation is not a grounding
|
|
426
466
|
link, so write it exactly as returned (tags, `claim_text`, `document.body`, no
|
|
427
467
|
`claim_key`, no relationships). Record an ontology gap only when no returned schema fits the
|
|
@@ -23,8 +23,10 @@ drift diagnostic. Unresolved Git index conflicts are likewise blocking; Kibi
|
|
|
23
23
|
never chooses a merge winner.
|
|
24
24
|
|
|
25
25
|
Relationship upserts and relationship deletes patch only the canonical shard,
|
|
26
|
-
preserving unrelated records. Authored entity deletion
|
|
27
|
-
|
|
26
|
+
preserving unrelated records. Authored entity deletion writes nothing and
|
|
27
|
+
returns a hash-bound plan (`outcome: plan_returned`); approve it by running the
|
|
28
|
+
returned `nextActions[0]` (`kb_apply_plan` with `{plan, approvedPlanHash}`)
|
|
29
|
+
unchanged, or by repeating `kb_delete` with `approvedPlanHash`. Evolve requirements with a new
|
|
28
30
|
requirement and `supersedes`, rather than deleting the old semantic claim.
|
|
29
31
|
|
|
30
32
|
On `committed_with_repairs`, inspect `effects` and execute the typed required
|
|
@@ -61,6 +61,16 @@ export type RemovedRelationshipRecords = Readonly<{
|
|
|
61
61
|
* approve the bytes before writing (deletion plans) render without writing.
|
|
62
62
|
*/
|
|
63
63
|
export declare function renderShardWithout(text: string, selectors: readonly RelationshipSelector[], shardPath: string): string;
|
|
64
|
+
export type PlannedShardRemovals = Readonly<{
|
|
65
|
+
removals: RemovedRelationshipRecords[];
|
|
66
|
+
/** Shard path -> its body without the selected records. */
|
|
67
|
+
bodies: ReadonlyMap<string, string>;
|
|
68
|
+
}>;
|
|
69
|
+
/**
|
|
70
|
+
* Render every shard that holds a selected relationship without writing it,
|
|
71
|
+
* so a dry run can report the exact bytes a delete would publish.
|
|
72
|
+
*/
|
|
73
|
+
export declare function planRelationshipShardRemovals(kbRoot: string, selectors: readonly RelationshipSelector[]): PlannedShardRemovals;
|
|
64
74
|
export declare function removeRelationshipsFromShards(kbRoot: string, selectors: readonly RelationshipSelector[]): RemovedRelationshipRecords[];
|
|
65
75
|
/**
|
|
66
76
|
* Appends a relationship to the appropriate shard.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shards.d.ts","sourceRoot":"","sources":["../../src/relationships/shards.ts"],"names":[],"mappings":"AAwBA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGzE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAOjE;AAED;;;GAGG;AAEH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,kBAAkB,EAAE,CAgFtB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,kBAAkB,EAAE,GAC5B,IAAI,CAON;AAwCD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC,CAAC;AAEH;;;GAGG;AACH;;;;GAIG;AAEH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,SAAS,oBAAoB,EAAE,EAC1C,SAAS,EAAE,MAAM,GAChB,MAAM,CA2BR;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,oBAAoB,EAAE,GACzC,0BAA0B,EAAE,
|
|
1
|
+
{"version":3,"file":"shards.d.ts","sourceRoot":"","sources":["../../src/relationships/shards.ts"],"names":[],"mappings":"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"}
|
|
@@ -197,15 +197,21 @@ export function renderShardWithout(text, selectors, shardPath) {
|
|
|
197
197
|
}
|
|
198
198
|
return document.toString();
|
|
199
199
|
}
|
|
200
|
-
|
|
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
|
-
|
|
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
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
selector
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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": {
|
package/dist/search-answer.d.ts
CHANGED
|
@@ -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
|
|
73
|
-
*
|
|
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":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"search-answer.d.ts","sourceRoot":"","sources":["../src/search-answer.ts"],"names":[],"mappings":"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"}
|
package/dist/search-answer.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
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)
|
|
105
|
-
:
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
880
|
+
note: answerNote(governing.length, detailedUngoverned),
|
|
783
881
|
};
|
|
784
882
|
return fitSearchAnswer(answer, limits.maxBytes);
|
|
785
883
|
}
|
package/dist/types/entities.d.ts
CHANGED
|
@@ -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 = {
|