kibi-cli 2.36.0 → 2.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-json-command.d.ts.map +1 -1
- package/dist/cli-json-command.js +4 -0
- package/dist/cli-operation-metadata.d.ts +1 -1
- package/dist/cli-operation-metadata.js +1 -1
- package/dist/cli-register-foundation.d.ts.map +1 -1
- package/dist/cli-register-foundation.js +2 -1
- package/dist/cli-register-maintenance.d.ts.map +1 -1
- package/dist/cli-register-maintenance.js +5 -0
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +1 -0
- package/dist/cli-validate.d.ts.map +1 -1
- package/dist/cli-validate.js +21 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +19 -1
- package/dist/commands/aggregated-checks.d.ts.map +1 -1
- package/dist/commands/aggregated-checks.js +89 -16
- package/dist/commands/coverage.d.ts +1 -0
- package/dist/commands/coverage.d.ts.map +1 -1
- package/dist/commands/coverage.js +40 -0
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +70 -35
- package/dist/commands/github-init.d.ts.map +1 -1
- package/dist/commands/github-init.js +4 -2
- package/dist/commands/hook-managers.d.ts +43 -0
- package/dist/commands/hook-managers.d.ts.map +1 -0
- package/dist/commands/hook-managers.js +426 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +40 -5
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +9 -3
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +49 -1
- package/dist/commands/telemetry.d.ts +7 -0
- package/dist/commands/telemetry.d.ts.map +1 -0
- package/dist/commands/telemetry.js +23 -0
- package/dist/decision-firmness.d.ts.map +1 -1
- package/dist/decision-firmness.js +11 -14
- package/dist/engine-limits.d.ts.map +1 -1
- package/dist/engine-limits.js +8 -10
- package/dist/entity-body-context.d.ts.map +1 -1
- package/dist/entity-body-context.js +39 -36
- package/dist/extractors/markdown.d.ts +6 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +21 -0
- package/dist/extractors/symbol-coordinates.d.ts.map +1 -1
- package/dist/extractors/symbol-coordinates.js +23 -4
- package/dist/firm-decision-edit.d.ts.map +1 -1
- package/dist/firm-decision-edit.js +1 -3
- package/dist/intent-search.d.ts +5 -1
- package/dist/intent-search.d.ts.map +1 -1
- package/dist/intent-search.js +118 -33
- package/dist/logic/ir.d.ts.map +1 -1
- package/dist/logic/ir.js +82 -108
- package/dist/operations/bootstrap/discovery-evidence.d.ts.map +1 -1
- package/dist/operations/bootstrap/discovery-evidence.js +44 -2
- package/dist/operations/bootstrap/discovery.d.ts.map +1 -1
- package/dist/operations/bootstrap/discovery.js +1 -0
- package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
- package/dist/operations/bootstrap/guidance-actions.js +2 -1
- package/dist/operations/bootstrap/plugin-offers.d.ts +11 -2
- package/dist/operations/bootstrap/plugin-offers.d.ts.map +1 -1
- package/dist/operations/bootstrap/plugin-offers.js +48 -9
- package/dist/operations/proof/claim-bindings.d.ts.map +1 -1
- package/dist/operations/proof/claim-bindings.js +1 -0
- package/dist/operations/proof/code-certificates.d.ts +2 -0
- package/dist/operations/proof/code-certificates.d.ts.map +1 -1
- package/dist/operations/proof/code-certificates.js +34 -14
- package/dist/operations/proof/code-models.d.ts.map +1 -1
- package/dist/operations/proof/code-models.js +19 -5
- package/dist/operations/proof/code-runner.d.ts +16 -0
- package/dist/operations/proof/code-runner.d.ts.map +1 -1
- package/dist/operations/proof/code-runner.js +42 -6
- package/dist/operations/proof/explain.d.ts +63 -0
- package/dist/operations/proof/explain.d.ts.map +1 -1
- package/dist/operations/proof/explain.js +162 -0
- package/dist/operations/semantic-advisor/analyze-prose.d.ts +9 -1
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +21 -0
- package/dist/operations/semantic-advisor/case-preview.d.ts +24 -0
- package/dist/operations/semantic-advisor/case-preview.d.ts.map +1 -0
- package/dist/operations/semantic-advisor/case-preview.js +216 -0
- package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/shared.js +3 -0
- package/dist/operations/semantic-advisor/types.d.ts +23 -0
- package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
- package/dist/plugins/approved-source-analyzers.generated.d.ts +11 -8
- package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -1
- package/dist/plugins/approved-source-analyzers.generated.js +11 -8
- package/dist/plugins/compose-search-hints.d.ts +29 -0
- package/dist/plugins/compose-search-hints.d.ts.map +1 -0
- package/dist/plugins/compose-search-hints.js +94 -0
- package/dist/plugins/external-allowlist.d.ts +7 -0
- package/dist/plugins/external-allowlist.d.ts.map +1 -1
- package/dist/plugins/external-allowlist.js +11 -0
- package/dist/plugins/registry.d.ts +8 -1
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +22 -3
- package/dist/plugins/source-classification.d.ts +2 -2
- package/dist/plugins/source-classification.d.ts.map +1 -1
- package/dist/plugins/source-classification.js +25 -1
- package/dist/prolog/codec.d.ts.map +1 -1
- package/dist/prolog/codec.js +10 -20
- package/dist/public/impact/coverage-depth-quality.d.ts.map +1 -1
- package/dist/public/impact/coverage-depth-quality.js +32 -16
- package/dist/public/impact/full-kb-quality.d.ts +6 -0
- package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
- package/dist/public/impact/full-kb-quality.js +8 -3
- package/dist/public/impact/requirement-quality.d.ts.map +1 -1
- package/dist/public/impact/requirement-quality.js +56 -29
- package/dist/public/operations/catalog.d.ts +44 -4
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/check-executor.d.ts +6 -0
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +34 -2
- package/dist/public/operations/discovery-executors.d.ts +5 -1
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +65 -4
- package/dist/public/operations/evidence-floor.d.ts +8 -1
- package/dist/public/operations/evidence-floor.d.ts.map +1 -1
- package/dist/public/operations/evidence-floor.js +3 -4
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +41 -10
- package/dist/public/operations/node-ports.d.ts.map +1 -1
- package/dist/public/operations/node-ports.js +3 -1
- package/dist/public/operations/repair-plan.d.ts +46 -0
- package/dist/public/operations/repair-plan.d.ts.map +1 -1
- package/dist/public/operations/repair-plan.js +110 -1
- package/dist/public/operations/schema6-check-actions.js +1 -1
- package/dist/public/operations/source-analysis-cache.d.ts +22 -0
- package/dist/public/operations/source-analysis-cache.d.ts.map +1 -0
- package/dist/public/operations/source-analysis-cache.js +157 -0
- 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 +2 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/discovery.d.ts +7 -2
- package/dist/public/operations/specs/discovery.d.ts.map +1 -1
- package/dist/public/operations/specs/discovery.js +7 -2
- package/dist/public/operations/specs/mutation-schemas.d.ts +36 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +30 -0
- package/dist/public/operations/specs/upsert.d.ts +36 -1
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/operations/symbol-granularity-check.d.ts +3 -1
- package/dist/public/operations/symbol-granularity-check.d.ts.map +1 -1
- package/dist/public/operations/symbol-granularity-check.js +21 -7
- package/dist/public/proof-protocol.d.ts +6 -1
- package/dist/public/proof-protocol.d.ts.map +1 -1
- package/dist/public/proof-protocol.js +12 -3
- package/dist/public/proof-sources.d.ts +2 -0
- package/dist/public/proof-sources.d.ts.map +1 -1
- package/dist/public/proof-sources.js +32 -6
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +59 -0
- package/dist/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/dist/public/skills/kibi-commit-review/SKILL.md +6 -2
- package/dist/public/skills/kibi-decisions/SKILL.md +7 -2
- package/dist/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/dist/public/skills/kibi-usage/SKILL.md +50 -3
- package/dist/public/skills/kibi-usage/resources/fact-lanes.md +34 -0
- package/dist/public/skills/kibi-usage/resources/proof.md +13 -5
- package/dist/public/skills/kibi-usage/resources/workflows.md +10 -0
- package/dist/relationships/shards.d.ts +2 -0
- package/dist/relationships/shards.d.ts.map +1 -1
- package/dist/relationships/shards.js +25 -1
- package/dist/schemas/entity.schema.json +98 -1
- package/dist/search-answer.d.ts +3 -2
- package/dist/search-answer.d.ts.map +1 -1
- package/dist/search-answer.js +57 -4
- package/dist/search-hints.d.ts +58 -0
- package/dist/search-hints.d.ts.map +1 -0
- package/dist/search-hints.js +187 -0
- package/dist/search-ranking.d.ts +7 -0
- package/dist/search-ranking.d.ts.map +1 -1
- package/dist/search-ranking.js +54 -56
- package/dist/search-token-cache.d.ts +30 -0
- package/dist/search-token-cache.d.ts.map +1 -0
- package/dist/search-token-cache.js +86 -0
- package/dist/traceability/impact-knowledge.d.ts.map +1 -1
- package/dist/traceability/impact-knowledge.js +2 -0
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +11 -1
- package/dist/types/entities.d.ts +12 -0
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/usage-telemetry.d.ts +20 -0
- package/dist/usage-telemetry.d.ts.map +1 -0
- package/dist/usage-telemetry.js +93 -0
- package/dist/utils/branch-resolver.d.ts.map +1 -1
- package/dist/utils/branch-resolver.js +1 -0
- package/dist/utils/rule-registry.generated.d.ts +5 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +6 -0
- package/package.json +5 -4
- package/schema/entities.pl +12 -0
- package/src/public/impact/coverage-depth-quality.ts +59 -21
- package/src/public/impact/full-kb-quality.ts +15 -1
- package/src/public/impact/requirement-quality.ts +95 -38
- package/src/public/operations/check-executor.ts +41 -1
- package/src/public/operations/discovery-executors.ts +92 -4
- package/src/public/operations/evidence-floor.ts +15 -3
- package/src/public/operations/migration-plan.ts +41 -9
- package/src/public/operations/node-ports.ts +3 -1
- package/src/public/operations/repair-plan.ts +152 -1
- package/src/public/operations/schema6-check-actions.ts +1 -1
- package/src/public/operations/source-analysis-cache.ts +196 -0
- package/src/public/operations/specs/check-rules.generated.ts +2 -1
- package/src/public/operations/specs/discovery.ts +8 -2
- package/src/public/operations/specs/mutation-schemas.ts +34 -0
- package/src/public/operations/symbol-granularity-check.ts +25 -5
- package/src/public/proof-protocol-types.d.ts +1 -1
- package/src/public/proof-protocol.ts +18 -4
- package/src/public/proof-sources.ts +37 -6
- package/src/public/schemas/entity.ts +65 -0
- package/src/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/src/public/skills/kibi-commit-review/SKILL.md +6 -2
- package/src/public/skills/kibi-decisions/SKILL.md +7 -2
- package/src/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/src/public/skills/kibi-usage/SKILL.md +50 -3
- package/src/public/skills/kibi-usage/resources/fact-lanes.md +34 -0
- package/src/public/skills/kibi-usage/resources/proof.md +13 -5
- package/src/public/skills/kibi-usage/resources/workflows.md +10 -0
- package/src/schemas/entity.schema.json +98 -1
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { mkdirSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { runtimeDirectory } from "./engine.js";
|
|
5
|
+
import { NON_GOVERNING_STATUSES, queryGraphEdges, } from "./intent-search.js";
|
|
6
|
+
import { composeSearchHints, } from "./plugins/compose-search-hints.js";
|
|
7
|
+
import { isProvenanceStub } from "./provenance-stub.js";
|
|
8
|
+
import { loadMarkdownBodySync } from "./search-ranking.js";
|
|
9
|
+
import { tokenSourceHash } from "./search-token-cache.js";
|
|
10
|
+
/**
|
|
11
|
+
* Below this top score a lexical answer is weak enough to show hints. On
|
|
12
|
+
* Kibi's own KB, 17 of 18 reworded questions the ranker got wrong scored
|
|
13
|
+
* below it, against 6 of 30 gold questions it got right. Host-owned, so no
|
|
14
|
+
* provider can move it.
|
|
15
|
+
*/
|
|
16
|
+
// implements REQ-kibi-search-hints-host
|
|
17
|
+
export const SEARCH_HINT_WEAK_SCORE = 0.44;
|
|
18
|
+
/** Requirements shown as hints. */
|
|
19
|
+
// implements REQ-kibi-search-hints-host
|
|
20
|
+
export const SEARCH_HINT_LIMIT = 10;
|
|
21
|
+
/** Entities asked of the provider before they are lifted to requirements. */
|
|
22
|
+
const PROVIDER_LIMIT = 20;
|
|
23
|
+
/** Text a provider sees per entity: title, statement, then body. */
|
|
24
|
+
const ENTITY_TEXT_CHARS = 2000;
|
|
25
|
+
/** A provider's first call in a process may build its index. */
|
|
26
|
+
const FIRST_CALL_TIMEOUT_MS = 3000;
|
|
27
|
+
const WARM_CALL_TIMEOUT_MS = 500;
|
|
28
|
+
/** Providers that answered once in this process; later calls get less time. */
|
|
29
|
+
const warmedProviders = new WeakSet();
|
|
30
|
+
/** Why a lexical answer needs hints, or null when it is strong enough. */
|
|
31
|
+
// implements REQ-kibi-search-hints-host
|
|
32
|
+
export function searchHintsTrigger(analysis) {
|
|
33
|
+
if (analysis.abstained || analysis.topScore === null)
|
|
34
|
+
return "abstained";
|
|
35
|
+
return analysis.topScore < SEARCH_HINT_WEAK_SCORE ? "weak" : null;
|
|
36
|
+
}
|
|
37
|
+
function isCurrent(entity) {
|
|
38
|
+
const status = String(entity.status).trim().toLowerCase();
|
|
39
|
+
return (!NON_GOVERNING_STATUSES.has(status) &&
|
|
40
|
+
status !== "closed" &&
|
|
41
|
+
!isProvenanceStub(entity));
|
|
42
|
+
}
|
|
43
|
+
function entityBody(entity, bodies, workspaceRoot) {
|
|
44
|
+
// The ranking may not have read every body; read the rest so an entity's
|
|
45
|
+
// text, and so its cached vector, never depends on the query.
|
|
46
|
+
const source = entity.source;
|
|
47
|
+
if (typeof source !== "string")
|
|
48
|
+
return "";
|
|
49
|
+
if (!bodies.has(source))
|
|
50
|
+
bodies.set(source, loadMarkdownBodySync(source, workspaceRoot));
|
|
51
|
+
return bodies.get(source);
|
|
52
|
+
}
|
|
53
|
+
function entityText(entity, bodies, workspaceRoot) {
|
|
54
|
+
return [
|
|
55
|
+
entity.title,
|
|
56
|
+
entity.semantic_text,
|
|
57
|
+
entityBody(entity, bodies, workspaceRoot),
|
|
58
|
+
]
|
|
59
|
+
.filter((part) => typeof part === "string" && part !== "")
|
|
60
|
+
.join("\n")
|
|
61
|
+
.slice(0, ENTITY_TEXT_CHARS);
|
|
62
|
+
}
|
|
63
|
+
/** The current entities a provider may hint at, as the search loaded them. */
|
|
64
|
+
// implements REQ-kibi-search-hints-host
|
|
65
|
+
export function searchHintsEntities(entities, bodies, workspaceRoot) {
|
|
66
|
+
const seen = new Set();
|
|
67
|
+
const rows = [];
|
|
68
|
+
for (const entity of entities) {
|
|
69
|
+
const id = String(entity.id ?? "");
|
|
70
|
+
if (id === "" || seen.has(id) || !isCurrent(entity))
|
|
71
|
+
continue;
|
|
72
|
+
seen.add(id);
|
|
73
|
+
const text = entityText(entity, bodies, workspaceRoot);
|
|
74
|
+
rows.push({
|
|
75
|
+
id,
|
|
76
|
+
type: String(entity.type ?? ""),
|
|
77
|
+
title: String(entity.title ?? ""),
|
|
78
|
+
text,
|
|
79
|
+
hash: tokenSourceHash([text]),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return rows;
|
|
83
|
+
}
|
|
84
|
+
function cacheDirectory(workspaceRoot) {
|
|
85
|
+
const workspace = createHash("sha256")
|
|
86
|
+
.update(path.resolve(workspaceRoot))
|
|
87
|
+
.digest("hex")
|
|
88
|
+
.slice(0, 24);
|
|
89
|
+
const directory = path.join(runtimeDirectory(), `search-hints-${workspace}`);
|
|
90
|
+
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
91
|
+
return directory;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* A hint on a scenario, test, fact or ADR is shown as the current
|
|
95
|
+
* requirement it belongs to, so the agent re-asks about what governs; an
|
|
96
|
+
* entity no current requirement links to is shown as itself.
|
|
97
|
+
*/
|
|
98
|
+
async function liftToRequirements(prolog, hints, byId) {
|
|
99
|
+
const isRequirement = (id) => byId.get(id)?.type === "req";
|
|
100
|
+
const seeds = new Set(hints.map((hint) => hint.id).filter((id) => !isRequirement(id)));
|
|
101
|
+
const requirementsOf = new Map();
|
|
102
|
+
for (const edge of await queryGraphEdges(prolog, [...seeds]))
|
|
103
|
+
for (const [seed, other] of [
|
|
104
|
+
[edge.from, edge.to],
|
|
105
|
+
[edge.to, edge.from],
|
|
106
|
+
])
|
|
107
|
+
if (seeds.has(seed) && isRequirement(other))
|
|
108
|
+
requirementsOf.set(seed, (requirementsOf.get(seed) ?? new Set()).add(other));
|
|
109
|
+
const items = [];
|
|
110
|
+
const shown = new Set();
|
|
111
|
+
for (const hint of hints) {
|
|
112
|
+
const linked = requirementsOf.get(hint.id);
|
|
113
|
+
for (const target of linked ? [...linked].sort() : [hint.id]) {
|
|
114
|
+
if (shown.has(target))
|
|
115
|
+
continue;
|
|
116
|
+
shown.add(target);
|
|
117
|
+
items.push({
|
|
118
|
+
id: target,
|
|
119
|
+
title: byId.get(target).title,
|
|
120
|
+
score: hint.score,
|
|
121
|
+
...(target !== hint.id ? { via: hint.id } : {}),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return items;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Ask the configured kibi.search-hints.v1 provider which current entities a
|
|
129
|
+
* weakly answered question is probably about. Returns undefined when the
|
|
130
|
+
* answer is strong or no provider is configured. Hints never change the
|
|
131
|
+
* ranked results, the governing answer or abstention.
|
|
132
|
+
*/
|
|
133
|
+
// implements REQ-kibi-search-hints-host
|
|
134
|
+
export async function buildSearchHints(options) {
|
|
135
|
+
const trigger = searchHintsTrigger(options.analysis);
|
|
136
|
+
if (trigger === null)
|
|
137
|
+
return undefined;
|
|
138
|
+
const { resolution } = options;
|
|
139
|
+
if (resolution.replace === null && resolution.shadow.length === 0)
|
|
140
|
+
return undefined;
|
|
141
|
+
const entities = searchHintsEntities(options.entities, options.bodies, options.workspaceRoot);
|
|
142
|
+
if (entities.length === 0)
|
|
143
|
+
return undefined;
|
|
144
|
+
const composed = await composeSearchHints(resolution, {
|
|
145
|
+
query: options.query,
|
|
146
|
+
limit: PROVIDER_LIMIT,
|
|
147
|
+
entities,
|
|
148
|
+
cacheDirectory: cacheDirectory(options.workspaceRoot),
|
|
149
|
+
}, {
|
|
150
|
+
operationName: "kb_search",
|
|
151
|
+
timeoutMs: (binding) => warmedProviders.has(binding.capability)
|
|
152
|
+
? WARM_CALL_TIMEOUT_MS
|
|
153
|
+
: FIRST_CALL_TIMEOUT_MS,
|
|
154
|
+
});
|
|
155
|
+
for (const binding of [resolution.replace, ...resolution.shadow])
|
|
156
|
+
if (binding)
|
|
157
|
+
warmedProviders.add(binding.capability);
|
|
158
|
+
const byId = new Map(entities.map((entity) => [entity.id, entity]));
|
|
159
|
+
const answered = new Set(options.governingIds.slice(0, 3));
|
|
160
|
+
const items = (await liftToRequirements(options.prolog, composed.hints, byId))
|
|
161
|
+
.filter((item) => !answered.has(item.id))
|
|
162
|
+
.slice(0, SEARCH_HINT_LIMIT);
|
|
163
|
+
const shadow = composed.shadowComparisons.map((comparison) => ({
|
|
164
|
+
provider: comparison.stamp,
|
|
165
|
+
items: comparison.hints,
|
|
166
|
+
}));
|
|
167
|
+
return {
|
|
168
|
+
trigger,
|
|
169
|
+
provider: composed.stamp,
|
|
170
|
+
items,
|
|
171
|
+
...(shadow.length > 0 ? { shadow } : {}),
|
|
172
|
+
...(composed.diagnostics.length > 0
|
|
173
|
+
? { diagnostics: composed.diagnostics }
|
|
174
|
+
: {}),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/** The sentence a search answer's text adds when hints are shown. */
|
|
178
|
+
// implements REQ-kibi-search-hints-host
|
|
179
|
+
export function searchHintsNote(hints) {
|
|
180
|
+
if (hints === undefined || hints.items.length === 0)
|
|
181
|
+
return "";
|
|
182
|
+
const named = hints.items
|
|
183
|
+
.slice(0, 5)
|
|
184
|
+
.map((item) => `${item.title} (${item.id})`)
|
|
185
|
+
.join("; ");
|
|
186
|
+
return ` The lexical answer is weak; by meaning the KB may describe this as: ${named}. Re-ask in those words or pass them as semanticFacets.aliases, then read the governing requirement with kb_query. Hints are suggestions, not governing requirements.`;
|
|
187
|
+
}
|
package/dist/search-ranking.d.ts
CHANGED
|
@@ -6,5 +6,12 @@ export interface SearchMatch {
|
|
|
6
6
|
}
|
|
7
7
|
export declare function rankEntities(entities: Record<string, unknown>[], query: string, workspaceRoot: string): Promise<SearchMatch[]>;
|
|
8
8
|
export declare function loadMarkdownBody(source: string, workspaceRoot: string): Promise<string | null>;
|
|
9
|
+
/**
|
|
10
|
+
* loadMarkdownBody, reading synchronously. Search reads the bodies of
|
|
11
|
+
* thousands of candidates at once; each asynchronous read is four thread-pool
|
|
12
|
+
* round trips (open, stat, read, close), which made reading them take ten
|
|
13
|
+
* times as long as reading them in turn.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadMarkdownBodySync(source: string, workspaceRoot: string): string | null;
|
|
9
16
|
export declare function snippetFromMatchedLine(matchedLine: string | undefined): string | undefined;
|
|
10
17
|
//# sourceMappingURL=search-ranking.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-ranking.d.ts","sourceRoot":"","sources":["../src/search-ranking.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"search-ranking.d.ts","sourceRoot":"","sources":["../src/search-ranking.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAiDD,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EACnC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,WAAW,EAAE,CAAC,CAmCxB;AAsGD,wBAAsB,gBAAgB,CAEpC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxB;AAED;;;;;GAKG;AAEH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GACpB,MAAM,GAAG,IAAI,CAQf;AA4ID,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,MAAM,GAAG,SAAS,CAQpB"}
|
package/dist/search-ranking.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import syncFs from "node:fs";
|
|
1
2
|
import fs from "node:fs/promises";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { bodySnippetLine } from "./entity-body-context.js";
|
|
@@ -38,9 +39,8 @@ const SEARCH_STOP_WORDS = new Set([
|
|
|
38
39
|
// implements REQ-mcp-search-discovery, REQ-002, REQ-003, REQ-bootstrap-provenance-stubs
|
|
39
40
|
export async function rankEntities(entities, query, workspaceRoot) {
|
|
40
41
|
const queryContext = buildSearchQueryContext(query);
|
|
41
|
-
if (
|
|
42
|
+
if (queryContext.signalTokens.length === 0)
|
|
42
43
|
return [];
|
|
43
|
-
}
|
|
44
44
|
const matches = [];
|
|
45
45
|
for (const entity of entities) {
|
|
46
46
|
const match = await rankEntity(entity, queryContext, workspaceRoot);
|
|
@@ -82,8 +82,8 @@ async function rankEntity(entity, queryContext, workspaceRoot) {
|
|
|
82
82
|
const tags = Array.isArray(entity.tags)
|
|
83
83
|
? entity.tags.map((tag) => String(tag))
|
|
84
84
|
: [];
|
|
85
|
-
const titleForms =
|
|
86
|
-
const idForms =
|
|
85
|
+
const titleForms = searchText(title);
|
|
86
|
+
const idForms = searchText(id);
|
|
87
87
|
if (isExactSearchMatch(titleForms, queryContext.phrase)) {
|
|
88
88
|
score += 100;
|
|
89
89
|
reasons.push("exact title match");
|
|
@@ -101,12 +101,12 @@ async function rankEntity(entity, queryContext, workspaceRoot) {
|
|
|
101
101
|
reasons.push("ID match");
|
|
102
102
|
}
|
|
103
103
|
const metadataFields = [type, source, owner, priority, severity];
|
|
104
|
-
const metadataMatched = metadataFields.some((field) => isPhraseSearchMatch(
|
|
104
|
+
const metadataMatched = metadataFields.some((field) => isPhraseSearchMatch(searchText(field), queryContext.phrase));
|
|
105
105
|
if (metadataMatched) {
|
|
106
106
|
score += 20;
|
|
107
107
|
reasons.push("metadata match");
|
|
108
108
|
}
|
|
109
|
-
const matchingTags = tags.filter((tag) => isPhraseSearchMatch(
|
|
109
|
+
const matchingTags = tags.filter((tag) => isPhraseSearchMatch(searchText(tag), queryContext.phrase));
|
|
110
110
|
if (matchingTags.length > 0) {
|
|
111
111
|
score += 30;
|
|
112
112
|
reasons.push("tag match");
|
|
@@ -120,7 +120,7 @@ async function rankEntity(entity, queryContext, workspaceRoot) {
|
|
|
120
120
|
getInlineBodyText(entity);
|
|
121
121
|
let snippet;
|
|
122
122
|
if (bodyText) {
|
|
123
|
-
const bodyForms =
|
|
123
|
+
const bodyForms = searchText(bodyText);
|
|
124
124
|
if (isPhraseSearchMatch(bodyForms, queryContext.phrase)) {
|
|
125
125
|
score += 15;
|
|
126
126
|
reasons.push("markdown body match");
|
|
@@ -148,10 +148,37 @@ async function rankEntity(entity, queryContext, workspaceRoot) {
|
|
|
148
148
|
export async function loadMarkdownBody(
|
|
149
149
|
// implements REQ-007, REQ-mcp-search-discovery
|
|
150
150
|
source, workspaceRoot) {
|
|
151
|
-
|
|
151
|
+
const resolved = markdownBodyPath(source, workspaceRoot);
|
|
152
|
+
if (resolved === null)
|
|
153
|
+
return null;
|
|
154
|
+
try {
|
|
155
|
+
const fileContent = await fs.readFile(resolved, "utf8");
|
|
156
|
+
return stripFrontmatter(fileContent);
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* loadMarkdownBody, reading synchronously. Search reads the bodies of
|
|
164
|
+
* thousands of candidates at once; each asynchronous read is four thread-pool
|
|
165
|
+
* round trips (open, stat, read, close), which made reading them take ten
|
|
166
|
+
* times as long as reading them in turn.
|
|
167
|
+
*/
|
|
168
|
+
// implements REQ-mcp-search-discovery
|
|
169
|
+
export function loadMarkdownBodySync(source, workspaceRoot) {
|
|
170
|
+
const resolved = markdownBodyPath(source, workspaceRoot);
|
|
171
|
+
if (resolved === null)
|
|
172
|
+
return null;
|
|
173
|
+
try {
|
|
174
|
+
return stripFrontmatter(syncFs.readFileSync(resolved, "utf8"));
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
152
177
|
return null;
|
|
153
178
|
}
|
|
154
|
-
|
|
179
|
+
}
|
|
180
|
+
function markdownBodyPath(source, workspaceRoot) {
|
|
181
|
+
const normalizedSource = source.replace(/#.*/, "").trim();
|
|
155
182
|
if (!normalizedSource.endsWith(".md")) {
|
|
156
183
|
return null;
|
|
157
184
|
}
|
|
@@ -164,21 +191,13 @@ source, workspaceRoot) {
|
|
|
164
191
|
if (!resolved.startsWith(normalizedRoot + path.sep)) {
|
|
165
192
|
return null;
|
|
166
193
|
}
|
|
167
|
-
|
|
168
|
-
const fileContent = await fs.readFile(resolved, "utf8");
|
|
169
|
-
return stripFrontmatter(fileContent);
|
|
170
|
-
}
|
|
171
|
-
catch {
|
|
172
|
-
return null;
|
|
173
|
-
}
|
|
194
|
+
return resolved;
|
|
174
195
|
}
|
|
175
196
|
// implements REQ-mcp-search-discovery
|
|
176
197
|
function stripFrontmatter(content) {
|
|
177
198
|
const trimmedContent = content.trimStart();
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
const openingDelimiter = /^---[^\S\r\n]*(?:\r?\n|$)/.exec(trimmedContent);
|
|
199
|
+
// A delimiter at the very end leaves no room for a closing one.
|
|
200
|
+
const openingDelimiter = /^---[^\S\r\n]*\r?\n/.exec(trimmedContent);
|
|
182
201
|
if (!openingDelimiter) {
|
|
183
202
|
return content;
|
|
184
203
|
}
|
|
@@ -193,37 +212,17 @@ function stripFrontmatter(content) {
|
|
|
193
212
|
// implements REQ-mcp-search-discovery
|
|
194
213
|
function buildSearchQueryContext(query) {
|
|
195
214
|
return {
|
|
196
|
-
phrase:
|
|
197
|
-
signalTokens:
|
|
198
|
-
rawTrimmedQuery: query.trim(),
|
|
215
|
+
phrase: searchText(query),
|
|
216
|
+
signalTokens: Array.from(new Set(searchTokens(query).filter((token) => !SEARCH_STOP_WORDS.has(token)))),
|
|
199
217
|
};
|
|
200
218
|
}
|
|
201
219
|
// implements REQ-mcp-search-discovery
|
|
202
|
-
function
|
|
203
|
-
|
|
204
|
-
return {
|
|
205
|
-
normalized,
|
|
206
|
-
compact: normalized.replace(/\s+/g, ""),
|
|
207
|
-
};
|
|
220
|
+
function searchTokens(value) {
|
|
221
|
+
return Array.from(value.toLowerCase().matchAll(/[a-z0-9]+/g), (match) => singularizeSimplePlural(match[0]));
|
|
208
222
|
}
|
|
209
223
|
// implements REQ-mcp-search-discovery
|
|
210
|
-
function
|
|
211
|
-
return value
|
|
212
|
-
.trim()
|
|
213
|
-
.toLowerCase()
|
|
214
|
-
.replace(/[-_]+/g, " ")
|
|
215
|
-
.replace(/[^a-z0-9\s]+/g, " ")
|
|
216
|
-
.trim()
|
|
217
|
-
.split(/\s+/)
|
|
218
|
-
.filter(Boolean)
|
|
219
|
-
.map(singularizeSimplePlural)
|
|
220
|
-
.join(" ");
|
|
221
|
-
}
|
|
222
|
-
// implements REQ-mcp-search-discovery
|
|
223
|
-
function tokenizeSignalTerms(value) {
|
|
224
|
-
return Array.from(new Set(normalizeSearchText(value)
|
|
225
|
-
.split(/\s+/)
|
|
226
|
-
.filter((token) => token && !SEARCH_STOP_WORDS.has(token))));
|
|
224
|
+
function searchText(value) {
|
|
225
|
+
return searchTokens(value).join("");
|
|
227
226
|
}
|
|
228
227
|
// implements REQ-mcp-search-discovery
|
|
229
228
|
function singularizeSimplePlural(token) {
|
|
@@ -237,18 +236,19 @@ function singularizeSimplePlural(token) {
|
|
|
237
236
|
return token.slice(0, -1);
|
|
238
237
|
}
|
|
239
238
|
// implements REQ-mcp-search-discovery
|
|
239
|
+
// implements REQ-mcp-search-discovery
|
|
240
|
+
// The query phrase is never empty: a query without signal tokens ranks
|
|
241
|
+
// nothing.
|
|
240
242
|
function isExactSearchMatch(haystack, needle) {
|
|
241
|
-
return
|
|
242
|
-
(needle.compact !== "" && haystack.compact === needle.compact));
|
|
243
|
+
return haystack === needle;
|
|
243
244
|
}
|
|
244
245
|
// implements REQ-mcp-search-discovery
|
|
245
246
|
function isPhraseSearchMatch(haystack, needle) {
|
|
246
|
-
return
|
|
247
|
-
(needle.compact !== "" && haystack.compact.includes(needle.compact)));
|
|
247
|
+
return haystack.includes(needle);
|
|
248
248
|
}
|
|
249
249
|
// implements REQ-mcp-search-discovery
|
|
250
250
|
function countTokenMatches(haystack, tokens) {
|
|
251
|
-
return tokens.filter((token) => haystack.
|
|
251
|
+
return tokens.filter((token) => haystack.includes(token)).length;
|
|
252
252
|
}
|
|
253
253
|
// implements REQ-mcp-search-discovery
|
|
254
254
|
function getInlineBodyText(entity) {
|
|
@@ -267,13 +267,11 @@ function getInlineBodyText(entity) {
|
|
|
267
267
|
}
|
|
268
268
|
// implements REQ-mcp-search-discovery
|
|
269
269
|
function buildSnippet(bodyText, queryForms, entity) {
|
|
270
|
-
const lines = bodyText
|
|
271
|
-
.split(/\r?\n/)
|
|
272
|
-
.map((line) => line.trim())
|
|
273
|
-
.filter(Boolean);
|
|
270
|
+
const lines = bodyText.split(/\r?\n/).map((line) => line.trim());
|
|
274
271
|
// The line that matches the query wins; otherwise the context prose, then
|
|
275
272
|
// the first line.
|
|
276
|
-
const matchedLine = lines.find((line) => isPhraseSearchMatch(
|
|
273
|
+
const matchedLine = lines.find((line) => isPhraseSearchMatch(searchText(line), queryForms)) ??
|
|
274
|
+
bodySnippetLine(String(entity.type), bodyText, entity);
|
|
277
275
|
return snippetFromMatchedLine(matchedLine);
|
|
278
276
|
}
|
|
279
277
|
export function snippetFromMatchedLine(matchedLine) {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity tokens kept between searches. Every kb_search ranks nearly the whole
|
|
3
|
+
* KB, and each CLI call is a new process, so tokenizing every candidate again
|
|
4
|
+
* was most of a warm search. Each entry is keyed by entity and carries a hash
|
|
5
|
+
* of the text it was computed from, so an edited entity or body is
|
|
6
|
+
* tokenized again; the file also names the tokenizer it was built with, so a
|
|
7
|
+
* changed tokenizer starts an empty cache.
|
|
8
|
+
*/
|
|
9
|
+
export type CachedEntityTokens = Readonly<{
|
|
10
|
+
title: readonly string[];
|
|
11
|
+
metadata: readonly string[];
|
|
12
|
+
bodyTokens: readonly string[];
|
|
13
|
+
document: readonly string[];
|
|
14
|
+
}>;
|
|
15
|
+
/** Set to 0 to tokenize every search from scratch. */
|
|
16
|
+
export declare const KIBI_SEARCH_TOKEN_CACHE_ENV = "KIBI_SEARCH_TOKEN_CACHE";
|
|
17
|
+
export type SearchTokenCache = {
|
|
18
|
+
get(key: string, hash: string): CachedEntityTokens | undefined;
|
|
19
|
+
set(key: string, hash: string, tokens: CachedEntityTokens): void;
|
|
20
|
+
save(): void;
|
|
21
|
+
};
|
|
22
|
+
/** The hash an entry is checked against: every text its tokens come from. */
|
|
23
|
+
export declare function tokenSourceHash(parts: readonly string[]): string;
|
|
24
|
+
/**
|
|
25
|
+
* The token cache for `workspaceRoot`, built by `tokenizer` (a fingerprint
|
|
26
|
+
* of the tokenizing code). A cache that cannot be read starts empty and one
|
|
27
|
+
* that cannot be written is skipped: the cache only saves time.
|
|
28
|
+
*/
|
|
29
|
+
export declare function openSearchTokenCache(workspaceRoot: string, tokenizer: string): SearchTokenCache;
|
|
30
|
+
//# sourceMappingURL=search-token-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-token-cache.d.ts","sourceRoot":"","sources":["../src/search-token-cache.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AAGH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC,CAAC;AAaH,sDAAsD;AACtD,eAAO,MAAM,2BAA2B,4BAA4B,CAAC;AAErE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAC;IAC/D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACjE,IAAI,IAAI,IAAI,CAAC;CACd,CAAC;AAEF,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAEhE;AA2BD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAyClB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { runtimeDirectory } from "./engine.js";
|
|
5
|
+
/** Entries a cache file keeps; enough for a few branches of a large KB. */
|
|
6
|
+
const MAX_ENTRIES = 50_000;
|
|
7
|
+
/** Set to 0 to tokenize every search from scratch. */
|
|
8
|
+
export const KIBI_SEARCH_TOKEN_CACHE_ENV = "KIBI_SEARCH_TOKEN_CACHE";
|
|
9
|
+
/** The hash an entry is checked against: every text its tokens come from. */
|
|
10
|
+
export function tokenSourceHash(parts) {
|
|
11
|
+
return createHash("sha1").update(JSON.stringify(parts)).digest("base64");
|
|
12
|
+
}
|
|
13
|
+
function cacheFile(workspaceRoot) {
|
|
14
|
+
const workspace = createHash("sha256")
|
|
15
|
+
.update(path.resolve(workspaceRoot))
|
|
16
|
+
.digest("hex")
|
|
17
|
+
.slice(0, 24);
|
|
18
|
+
return path.join(runtimeDirectory(), `search-tokens-${workspace}.json`);
|
|
19
|
+
}
|
|
20
|
+
function readCache(file, tokenizer) {
|
|
21
|
+
try {
|
|
22
|
+
const parsed = JSON.parse(readFileSync(file, "utf8"));
|
|
23
|
+
if (parsed.version !== 1 || parsed.tokenizer !== tokenizer)
|
|
24
|
+
return new Map();
|
|
25
|
+
return new Map(Object.entries(parsed.entries));
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return new Map();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const NO_CACHE = {
|
|
32
|
+
get: () => undefined,
|
|
33
|
+
set: () => { },
|
|
34
|
+
save: () => { },
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* The token cache for `workspaceRoot`, built by `tokenizer` (a fingerprint
|
|
38
|
+
* of the tokenizing code). A cache that cannot be read starts empty and one
|
|
39
|
+
* that cannot be written is skipped: the cache only saves time.
|
|
40
|
+
*/
|
|
41
|
+
export function openSearchTokenCache(workspaceRoot, tokenizer) {
|
|
42
|
+
if (process.env[KIBI_SEARCH_TOKEN_CACHE_ENV] === "0")
|
|
43
|
+
return NO_CACHE;
|
|
44
|
+
let file;
|
|
45
|
+
try {
|
|
46
|
+
file = cacheFile(workspaceRoot);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return NO_CACHE;
|
|
50
|
+
}
|
|
51
|
+
const entries = readCache(file, tokenizer);
|
|
52
|
+
let dirty = false;
|
|
53
|
+
return {
|
|
54
|
+
get(key, hash) {
|
|
55
|
+
const entry = entries.get(key);
|
|
56
|
+
return entry !== undefined && entry.hash === hash ? entry : undefined;
|
|
57
|
+
},
|
|
58
|
+
set(key, hash, tokens) {
|
|
59
|
+
entries.delete(key);
|
|
60
|
+
entries.set(key, { hash, ...tokens });
|
|
61
|
+
dirty = true;
|
|
62
|
+
},
|
|
63
|
+
save() {
|
|
64
|
+
if (!dirty)
|
|
65
|
+
return;
|
|
66
|
+
dirty = false;
|
|
67
|
+
// Map order is insertion order and set() re-inserts, so the oldest
|
|
68
|
+
// entries are the ones dropped.
|
|
69
|
+
const kept = [...entries].slice(-MAX_ENTRIES);
|
|
70
|
+
const body = {
|
|
71
|
+
version: 1,
|
|
72
|
+
tokenizer,
|
|
73
|
+
entries: Object.fromEntries(kept),
|
|
74
|
+
};
|
|
75
|
+
const temporary = `${file}.${process.pid}.tmp`;
|
|
76
|
+
try {
|
|
77
|
+
writeFileSync(temporary, JSON.stringify(body), { mode: 0o600 });
|
|
78
|
+
renameSync(temporary, file);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// A runtime directory that is full or read-only only costs speed.
|
|
82
|
+
rmSync(temporary, { force: true });
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impact-knowledge.d.ts","sourceRoot":"","sources":["../../src/traceability/impact-knowledge.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EACL,KAAK,WAAW,EAIjB,MAAM,oBAAoB,CAAC;AAI5B,4EAA4E;AAE5E,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"impact-knowledge.d.ts","sourceRoot":"","sources":["../../src/traceability/impact-knowledge.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EACL,KAAK,WAAW,EAIjB,MAAM,oBAAoB,CAAC;AAI5B,4EAA4E;AAE5E,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAuFH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,MAAM,EACZ,SAAS,yDAAoE,GAC5E,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAyCxB;AAGD,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,MAAM,GACX,WAAW,CAiBb;AAGD,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,GACnC,WAAW,CAoBb;AAGD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,EACpC,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,MAAM,EAAE,CAsBV;AAeD,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,MAAM,GACX,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAiBxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temp-kb.d.ts","sourceRoot":"","sources":["../../src/traceability/temp-kb.ts"],"names":[],"mappings":"AAMA,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,OAAO,CAET;AACD,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;CACvB;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CASvC;AAQD;;;GAGG;AACH,wBAAgB,iBAAiB,CAE/B,OAAO,EAAE,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAA;CAAE,KAAK,aAAa,GACpE,IAAI,CAEN;
|
|
1
|
+
{"version":3,"file":"temp-kb.d.ts","sourceRoot":"","sources":["../../src/traceability/temp-kb.ts"],"names":[],"mappings":"AAMA,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,OAAO,CAET;AACD,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;CACvB;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CASvC;AAQD;;;GAGG;AACH,wBAAgB,iBAAiB,CAE/B,OAAO,EAAE,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAA;CAAE,KAAK,aAAa,GACpE,IAAI,CAEN;AAySD,iBAAe,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB/D;AAED,OAAO,EAAE,cAAc,EAAE,CAAC;AAe1B,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CA4Df;AAED,wBAAsB,YAAY,CAChC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,CAAC,CA+CxB;AAGD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAkBrE;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BlE"}
|
|
@@ -55,6 +55,10 @@ const FACT_STRING_FIELDS = new Set([
|
|
|
55
55
|
"canonical_key",
|
|
56
56
|
"claim_key",
|
|
57
57
|
"claim_text",
|
|
58
|
+
"dimension_waiver",
|
|
59
|
+
"dimension_waiver_approved_by",
|
|
60
|
+
"case_waiver",
|
|
61
|
+
"case_waiver_approved_by",
|
|
58
62
|
"predicate_name",
|
|
59
63
|
"predicate_namespace",
|
|
60
64
|
"rule_hash",
|
|
@@ -187,7 +191,13 @@ function buildEntityAssertionGoal(entity, sourceFile) {
|
|
|
187
191
|
if (entity.type === "req" && entity.semantic_inventory) {
|
|
188
192
|
props.push(`semantic_inventory=${toPrologString(JSON.stringify(entity.semantic_inventory))}`);
|
|
189
193
|
}
|
|
190
|
-
for (const field of [
|
|
194
|
+
for (const field of [
|
|
195
|
+
"approved_by",
|
|
196
|
+
"approval_ref",
|
|
197
|
+
"failure_side_waiver",
|
|
198
|
+
"failure_side_waiver_approved_by",
|
|
199
|
+
"rationale",
|
|
200
|
+
]) {
|
|
191
201
|
const value = entity.type === "req" ? entity[field] : undefined;
|
|
192
202
|
if (value !== undefined)
|
|
193
203
|
props.push(`${field}=${toPrologString(value)}`);
|
package/dist/types/entities.d.ts
CHANGED
|
@@ -37,6 +37,14 @@ export interface FactFields {
|
|
|
37
37
|
canonical_key?: string;
|
|
38
38
|
claim_key?: string;
|
|
39
39
|
claim_text?: string;
|
|
40
|
+
/** Why a quantifier word in claim_text ranges over nothing. */
|
|
41
|
+
dimension_waiver?: string;
|
|
42
|
+
/** The person who accepted the dimension waiver. */
|
|
43
|
+
dimension_waiver_approved_by?: string;
|
|
44
|
+
/** Why the fact's derived edge cases are covered some other way. */
|
|
45
|
+
case_waiver?: string;
|
|
46
|
+
/** The person who accepted the case waiver. */
|
|
47
|
+
case_waiver_approved_by?: string;
|
|
40
48
|
predicate_name?: string;
|
|
41
49
|
predicate_namespace?: string;
|
|
42
50
|
predicate_arity?: number;
|
|
@@ -66,6 +74,10 @@ export type Requirement = BaseEntity & {
|
|
|
66
74
|
approved_by?: string;
|
|
67
75
|
/** Optional reference to the approval decision record. */
|
|
68
76
|
approval_ref?: string;
|
|
77
|
+
/** Why the requirement has no failure side to test. */
|
|
78
|
+
failure_side_waiver?: string;
|
|
79
|
+
/** The person who accepted the failure-side waiver. */
|
|
80
|
+
failure_side_waiver_approved_by?: string;
|
|
69
81
|
/** Why the requirement exists; explanation, not checked meaning. */
|
|
70
82
|
rationale?: string;
|
|
71
83
|
/** How firmly it was decided; absent reads as `default` when an agent wrote it, else `firm`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/types/entities.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAGD,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EACN,SAAS,GACT,gBAAgB,GAChB,aAAa,GACb,MAAM,GACN,kBAAkB,GAClB,WAAW,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EACL,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,SAAS,GACT,UAAU,GACV,WAAW,GACX,UAAU,CAAC;IACf,UAAU,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,kBAAkB,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,YAAY,CAAC;IAC3D,wBAAwB,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACnD,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,cAAc,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IACzC,cAAc,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG;IACrC,IAAI,EAAE,KAAK,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;IAC9C,gGAAgG;IAChG,iBAAiB,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,YAAY,CAAC;IACpE,qFAAqF;IACrF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;AACzD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,sBAAsB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAChF,MAAM,MAAM,GAAG,GAAG,UAAU,GAAG;IAC7B,IAAI,EAAE,KAAK,CAAC;IACZ,gGAAgG;IAChG,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;CAC/C,CAAC;AACF,MAAM,MAAM,IAAI,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AACjD,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AACnD,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AACrD,MAAM,MAAM,IAAI,GAAG,UAAU,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9D,MAAM,MAAM,MAAM,GACd,WAAW,GACX,QAAQ,GACR,UAAU,GACV,GAAG,GACH,IAAI,GACJ,KAAK,GACL,MAAM,GACN,IAAI,CAAC"}
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/types/entities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
/**
|
|
3
|
+
* Name why this command failed with a fixed identifier (an error code, a
|
|
4
|
+
* failing doctor check), for the event recorded at exit. The first note wins.
|
|
5
|
+
*/
|
|
6
|
+
export declare function noteCliErrorCategory(category: string | undefined): void;
|
|
7
|
+
/** The error code of a failed JSON result printed by a command, if any. */
|
|
8
|
+
export declare function noteCliResultError(stdout: string | undefined): void;
|
|
9
|
+
/** Remember which registered command ran, for the event recorded at exit. */
|
|
10
|
+
export declare function trackCommandPath(program: Command): () => string | undefined;
|
|
11
|
+
export declare function finishCliTelemetry(input: {
|
|
12
|
+
readonly commandPath: string | undefined;
|
|
13
|
+
readonly packageVersion: string;
|
|
14
|
+
readonly startedAt: Date;
|
|
15
|
+
readonly exitCode: number;
|
|
16
|
+
/** The error the command threw, when it failed by throwing. */
|
|
17
|
+
readonly error?: unknown;
|
|
18
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=usage-telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-telemetry.d.ts","sourceRoot":"","sources":["../src/usage-telemetry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBzC;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAIvE;AAGD,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAanE;AAgBD,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,MAAM,GAAG,SAAS,CAc3E;AAGD,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAClC,GAAG,OAAO,CAAC,IAAI,CAAC,CAkChB"}
|