kibi-cli 2.31.1 → 2.32.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-register-proof.d.ts.map +1 -1
- package/dist/cli-register-proof.js +19 -7
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +2 -0
- package/dist/commands/check.d.ts +1 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +14 -5
- package/dist/commands/discovery-table.d.ts.map +1 -1
- package/dist/commands/discovery-table.js +51 -4
- package/dist/commands/doctor.js +19 -4
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +89 -3
- package/dist/commands/prove.d.ts +48 -1
- package/dist/commands/prove.d.ts.map +1 -1
- package/dist/commands/prove.js +293 -8
- package/dist/commands/report.d.ts +1 -0
- package/dist/commands/report.d.ts.map +1 -1
- package/dist/commands/report.js +70 -5
- package/dist/commands/signoff.d.ts.map +1 -1
- package/dist/commands/signoff.js +20 -1
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +20 -4
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +16 -5
- package/dist/diagnostics.js +1 -1
- package/dist/engine.js +1 -1
- package/dist/extractors/markdown.d.ts +3 -1
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +17 -0
- package/dist/operations/bootstrap/candidate-helpers.d.ts +3 -0
- package/dist/operations/bootstrap/candidate-helpers.d.ts.map +1 -1
- package/dist/operations/bootstrap/candidate-helpers.js +4 -0
- package/dist/operations/migration/evidence-floor.d.ts +41 -0
- package/dist/operations/migration/evidence-floor.d.ts.map +1 -0
- package/dist/operations/migration/evidence-floor.js +230 -0
- package/dist/operations/migration/proof-contract-claims.d.ts +59 -0
- package/dist/operations/migration/proof-contract-claims.d.ts.map +1 -0
- package/dist/operations/migration/proof-contract-claims.js +182 -0
- package/dist/operations/migration/schema6.d.ts +6 -0
- package/dist/operations/migration/schema6.d.ts.map +1 -1
- package/dist/operations/migration/schema6.js +94 -0
- package/dist/operations/mutation/omitted-properties.d.ts +11 -0
- package/dist/operations/mutation/omitted-properties.d.ts.map +1 -0
- package/dist/operations/mutation/omitted-properties.js +76 -0
- package/dist/operations/mutation/serialization.d.ts.map +1 -1
- package/dist/operations/mutation/serialization.js +1 -0
- package/dist/operations/mutation/strict-fact.d.ts.map +1 -1
- package/dist/operations/mutation/strict-fact.js +6 -2
- package/dist/operations/mutation/symbol-granularity.d.ts.map +1 -1
- package/dist/operations/mutation/symbol-granularity.js +5 -3
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +7 -1
- package/dist/operations/mutation/validation.d.ts +2 -0
- package/dist/operations/mutation/validation.d.ts.map +1 -1
- package/dist/operations/mutation/validation.js +4 -0
- package/dist/operations/proof/claim-bindings.d.ts +23 -0
- package/dist/operations/proof/claim-bindings.d.ts.map +1 -0
- package/dist/operations/proof/claim-bindings.js +211 -0
- package/dist/operations/proof/code-certificates.d.ts +135 -0
- package/dist/operations/proof/code-certificates.d.ts.map +1 -0
- package/dist/operations/proof/code-certificates.js +785 -0
- package/dist/operations/proof/code-scope.d.ts +11 -1
- package/dist/operations/proof/code-scope.d.ts.map +1 -1
- package/dist/operations/proof/code-scope.js +20 -2
- package/dist/operations/proof/compact-receipts.d.ts.map +1 -1
- package/dist/operations/proof/compact-receipts.js +4 -3
- package/dist/operations/proof/explain.d.ts +32 -0
- package/dist/operations/proof/explain.d.ts.map +1 -1
- package/dist/operations/proof/explain.js +91 -0
- package/dist/operations/proof/ingest-proof.d.ts +9 -1
- package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
- package/dist/operations/proof/ingest-proof.js +41 -2
- package/dist/operations/proof/receipt-compaction.d.ts +2 -0
- package/dist/operations/proof/receipt-compaction.d.ts.map +1 -1
- package/dist/operations/proof/receipt-compaction.js +6 -2
- package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/shared.js +4 -0
- package/dist/operations/semantic-advisor/strict-rules.js +3 -3
- package/dist/operations/semantic-advisor/types.d.ts +2 -1
- package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
- package/dist/plugins/approved-source-analyzers.generated.d.ts +6 -6
- package/dist/plugins/approved-source-analyzers.generated.js +6 -6
- package/dist/proof/command-test-report.d.ts +4 -3
- package/dist/proof/command-test-report.d.ts.map +1 -1
- package/dist/proof/command-test-report.js +4 -10
- package/dist/proof/evaluate.d.ts.map +1 -1
- package/dist/proof/evaluate.js +18 -2
- package/dist/proof/inspect.d.ts.map +1 -1
- package/dist/proof/inspect.js +58 -0
- package/dist/proof/producers/playwright-reporter.d.ts +3 -0
- package/dist/proof/producers/playwright-reporter.d.ts.map +1 -1
- package/dist/proof/producers/playwright-reporter.js +25 -2
- package/dist/proof/step-runner.d.ts +36 -0
- package/dist/proof/step-runner.d.ts.map +1 -0
- package/dist/proof/step-runner.js +234 -0
- package/dist/public/evidence-levels.d.ts +12 -0
- package/dist/public/evidence-levels.d.ts.map +1 -0
- package/dist/public/evidence-levels.js +19 -0
- package/dist/public/impact/coverage-depth-quality.d.ts +7 -0
- package/dist/public/impact/coverage-depth-quality.d.ts.map +1 -1
- package/dist/public/impact/coverage-depth-quality.js +59 -0
- package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
- package/dist/public/impact/full-kb-quality.js +3 -1
- package/dist/public/operations/catalog.d.ts +167 -6
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/check-executor.d.ts +2 -0
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +6 -0
- package/dist/public/operations/evidence-floor.d.ts +48 -0
- package/dist/public/operations/evidence-floor.d.ts.map +1 -0
- package/dist/public/operations/evidence-floor.js +143 -0
- package/dist/public/operations/migration-plan.d.ts +19 -5
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +22 -5
- package/dist/public/operations/node-ports.d.ts.map +1 -1
- package/dist/public/operations/node-ports.js +4 -1
- package/dist/public/operations/proof-contract-claims.d.ts +26 -0
- package/dist/public/operations/proof-contract-claims.d.ts.map +1 -0
- package/dist/public/operations/proof-contract-claims.js +71 -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 +3 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts +157 -5
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +15 -2
- package/dist/public/operations/specs/proof.d.ts +9 -0
- package/dist/public/operations/specs/proof.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.js +19 -10
- package/dist/public/operations/specs/upsert.d.ts +157 -5
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/proof-certificates.d.ts +89 -0
- package/dist/public/proof-certificates.d.ts.map +1 -0
- package/dist/public/proof-certificates.js +207 -0
- package/dist/public/proof-protocol.d.ts +126 -3
- package/dist/public/proof-protocol.d.ts.map +1 -1
- package/dist/public/proof-protocol.js +239 -3
- package/dist/public/proof-receipt.d.ts +89 -6
- package/dist/public/proof-receipt.d.ts.map +1 -1
- package/dist/public/proof-receipt.js +83 -7
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +18 -1
- package/dist/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/dist/public/skills/kibi-commit-review/SKILL.md +1 -1
- package/dist/public/skills/kibi-commit-review/resources/staged-gate.md +6 -1
- package/dist/public/skills/kibi-decisions/SKILL.md +10 -2
- package/dist/public/skills/kibi-decisions/resources/decision-records.md +6 -1
- package/dist/public/skills/kibi-freshness/SKILL.md +5 -1
- package/dist/public/skills/kibi-traceability/SKILL.md +11 -1
- package/dist/public/skills/kibi-usage/SKILL.md +6 -4
- package/dist/public/skills/kibi-usage/resources/proof.md +124 -19
- package/dist/public/skills/kibi-usage/resources/workflows.md +4 -4
- package/dist/report/html-report.css +38 -1
- package/dist/report/html-report.d.ts +8 -0
- package/dist/report/html-report.d.ts.map +1 -1
- package/dist/report/html-report.js +141 -6
- package/dist/report/report-view.d.ts +1 -1
- package/dist/report/report-view.d.ts.map +1 -1
- package/dist/report/report-view.js +7 -0
- package/dist/schemas/entity.schema.json +212 -4
- package/dist/search-answer.d.ts.map +1 -1
- package/dist/search-answer.js +1 -0
- package/dist/signoff/html.d.ts.map +1 -1
- package/dist/signoff/html.js +3 -0
- package/dist/signoff/markdown.d.ts.map +1 -1
- package/dist/signoff/markdown.js +3 -0
- package/dist/signoff/model.d.ts +20 -0
- package/dist/signoff/model.d.ts.map +1 -1
- package/dist/signoff/model.js +20 -1
- package/dist/traceability/impact-knowledge.d.ts.map +1 -1
- package/dist/traceability/impact-knowledge.js +1 -0
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +1 -0
- package/dist/types/entities.d.ts +4 -1
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/utils/merge-driver-setup.d.ts +8 -1
- package/dist/utils/merge-driver-setup.d.ts.map +1 -1
- package/dist/utils/merge-driver-setup.js +23 -2
- package/dist/utils/rule-registry.generated.d.ts +10 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +12 -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 +5 -1
- package/package.json +6 -2
- package/schema/entities.pl +6 -0
- package/schema/validation.pl +4 -1
- package/src/public/evidence-levels.ts +23 -0
- package/src/public/impact/coverage-depth-quality.ts +73 -0
- package/src/public/impact/full-kb-quality.ts +6 -1
- package/src/public/operations/check-executor.ts +13 -0
- package/src/public/operations/evidence-floor.ts +203 -0
- package/src/public/operations/migration-plan.ts +39 -6
- package/src/public/operations/node-ports.ts +3 -1
- package/src/public/operations/proof-contract-claims.ts +103 -0
- package/src/public/operations/specs/check-rules.generated.ts +3 -1
- package/src/public/operations/specs/mutation-schemas.ts +17 -2
- package/src/public/operations/specs/reporting.ts +20 -10
- package/src/public/proof-certificates.ts +271 -0
- package/src/public/proof-protocol-types.d.ts +17 -1
- package/src/public/proof-protocol.ts +318 -3
- package/src/public/proof-receipt.ts +127 -7
- package/src/public/schemas/entity.ts +19 -1
- package/src/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/src/public/skills/kibi-commit-review/SKILL.md +1 -1
- package/src/public/skills/kibi-commit-review/resources/staged-gate.md +6 -1
- package/src/public/skills/kibi-decisions/SKILL.md +10 -2
- package/src/public/skills/kibi-decisions/resources/decision-records.md +6 -1
- package/src/public/skills/kibi-freshness/SKILL.md +5 -1
- package/src/public/skills/kibi-traceability/SKILL.md +11 -1
- package/src/public/skills/kibi-usage/SKILL.md +6 -4
- package/src/public/skills/kibi-usage/resources/proof.md +124 -19
- package/src/public/skills/kibi-usage/resources/workflows.md +4 -4
- package/src/schemas/entity.schema.json +212 -4
- package/dist/commands/proof-impact.d.ts +0 -7
- package/dist/commands/proof-impact.d.ts.map +0 -1
- package/dist/commands/proof-impact.js +0 -39
- package/dist/operations/proof/baseline-diff.d.ts +0 -41
- package/dist/operations/proof/baseline-diff.d.ts.map +0 -1
- package/dist/operations/proof/baseline-diff.js +0 -153
- package/dist/operations/proof/impact.d.ts +0 -51
- package/dist/operations/proof/impact.d.ts.map +0 -1
- package/dist/operations/proof/impact.js +0 -138
|
@@ -2,8 +2,23 @@
|
|
|
2
2
|
export const PROOF_RUN_VERSION = "kibi.proof-run.v1" as const;
|
|
3
3
|
// implements REQ-kibi-verification-evidence-contract
|
|
4
4
|
export const PROOF_CONTRACT_VERSION = "kibi.proof-contract.v1" as const;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Receipts Kibi writes. v2 adds the contract's kind, the evidence level the
|
|
7
|
+
* receipt supports, and for certificate kinds the re-checked certificate.
|
|
8
|
+
*/
|
|
9
|
+
// implements REQ-kibi-verification-evidence-contract, REQ-kibi-code-proof-kinds
|
|
10
|
+
export const PROOF_RECEIPT_VERSION = "kibi.proof-receipt.v2" as const;
|
|
11
|
+
/** Receipts written before v2; still read, as e2e evidence at tested. */
|
|
12
|
+
// implements REQ-kibi-code-proof-kinds
|
|
13
|
+
export const PROOF_RECEIPT_V1_VERSION = "kibi.proof-receipt.v1" as const;
|
|
14
|
+
// implements REQ-kibi-code-proof-kinds
|
|
15
|
+
export const PROOF_RECEIPT_VERSIONS = [
|
|
16
|
+
PROOF_RECEIPT_V1_VERSION,
|
|
17
|
+
PROOF_RECEIPT_VERSION,
|
|
18
|
+
] as const;
|
|
19
|
+
/** The certificate a certificate-kind proof leaves for Kibi to re-check. */
|
|
20
|
+
// implements REQ-kibi-code-proof-kinds
|
|
21
|
+
export const CODE_CERTIFICATE_VERSION = "kibi.code-certificate.v1" as const;
|
|
7
22
|
// implements REQ-kibi-verification-evidence-contract
|
|
8
23
|
export const PROOF_INTEGRATION_VERSION = "kibi.proof-integration.v1" as const;
|
|
9
24
|
|
|
@@ -38,7 +53,52 @@ export const RUN_FAILURE_PHASES = [
|
|
|
38
53
|
"infrastructure",
|
|
39
54
|
] as const;
|
|
40
55
|
|
|
41
|
-
|
|
56
|
+
/**
|
|
57
|
+
* `all_required_first_attempt`: the whole run must pass and every obligation's
|
|
58
|
+
* own result must pass on its first attempt.
|
|
59
|
+
* `own_results_first_attempt`: a run whose only failures are other test cases
|
|
60
|
+
* (outcome `failed` in the execution phase) still proves an obligation whose
|
|
61
|
+
* own native-case result passed on its first attempt, so one unrelated
|
|
62
|
+
* failing case does not erase a suite's evidence. Aggregate-run obligations
|
|
63
|
+
* still need the whole run to pass.
|
|
64
|
+
*/
|
|
65
|
+
export const SUCCESS_POLICIES = [
|
|
66
|
+
"all_required_first_attempt",
|
|
67
|
+
"own_results_first_attempt",
|
|
68
|
+
] as const;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* What a proof contract's checker establishes. Runner kinds (e2e, example,
|
|
72
|
+
* property) sample cases and support tested evidence; certificate kinds
|
|
73
|
+
* (exhaustive, typecheck, arithmetic, smt) cover every case and support
|
|
74
|
+
* proved evidence once Kibi re-checks the certificate the run left.
|
|
75
|
+
*/
|
|
76
|
+
// implements REQ-kibi-code-proof-kinds
|
|
77
|
+
export const PROOF_KINDS = [
|
|
78
|
+
"e2e",
|
|
79
|
+
"example",
|
|
80
|
+
"property",
|
|
81
|
+
"exhaustive",
|
|
82
|
+
"typecheck",
|
|
83
|
+
"arithmetic",
|
|
84
|
+
"smt",
|
|
85
|
+
] as const;
|
|
86
|
+
|
|
87
|
+
// implements REQ-kibi-code-proof-kinds
|
|
88
|
+
export const CERTIFICATE_PROOF_KINDS = [
|
|
89
|
+
"exhaustive",
|
|
90
|
+
"typecheck",
|
|
91
|
+
"arithmetic",
|
|
92
|
+
"smt",
|
|
93
|
+
] as const;
|
|
94
|
+
|
|
95
|
+
// implements REQ-kibi-code-proof-kinds
|
|
96
|
+
export type ProofKind = (typeof PROOF_KINDS)[number];
|
|
97
|
+
|
|
98
|
+
// implements REQ-kibi-code-proof-kinds
|
|
99
|
+
export function isCertificateProofKind(kind: unknown): boolean {
|
|
100
|
+
return (CERTIFICATE_PROOF_KINDS as readonly unknown[]).includes(kind);
|
|
101
|
+
}
|
|
42
102
|
|
|
43
103
|
export type {
|
|
44
104
|
AttemptsStatus,
|
|
@@ -191,6 +251,13 @@ export const PROOF_RUN_ARTIFACT_SCHEMA = {
|
|
|
191
251
|
type: "array",
|
|
192
252
|
items: { type: "string", minLength: 1 },
|
|
193
253
|
},
|
|
254
|
+
certificates: {
|
|
255
|
+
type: "array",
|
|
256
|
+
description:
|
|
257
|
+
"kibi.code-certificate.v1 objects the run left for certificate-kind contracts, one per test. Kibi re-checks each before a receipt counts as proved.",
|
|
258
|
+
maxItems: 1000,
|
|
259
|
+
items: { type: "object", required: ["version", "kind", "test_id"] },
|
|
260
|
+
},
|
|
194
261
|
},
|
|
195
262
|
additionalProperties: false,
|
|
196
263
|
} as const;
|
|
@@ -218,6 +285,73 @@ export const PROOF_CONTRACT_SCHEMA = {
|
|
|
218
285
|
},
|
|
219
286
|
},
|
|
220
287
|
success_policy: { type: "string", enum: [...SUCCESS_POLICIES] },
|
|
288
|
+
kind: {
|
|
289
|
+
type: "string",
|
|
290
|
+
enum: [...PROOF_KINDS],
|
|
291
|
+
description:
|
|
292
|
+
"What the checker establishes; absent means e2e. exhaustive, typecheck, arithmetic and smt must leave a kibi.code-certificate.v1 that Kibi re-checks before the receipt counts as proved.",
|
|
293
|
+
},
|
|
294
|
+
domain_source: {
|
|
295
|
+
type: "object",
|
|
296
|
+
description:
|
|
297
|
+
"exhaustive and typecheck: the symbol that defines the finite domain. The proof must import it from its source file; a hand-listed domain downgrades the receipt to example. Kibi reads the export named `export`, or the symbol's title when `export` is absent.",
|
|
298
|
+
required: ["symbol_id"],
|
|
299
|
+
properties: {
|
|
300
|
+
symbol_id: { type: "string", minLength: 1 },
|
|
301
|
+
export: {
|
|
302
|
+
type: "string",
|
|
303
|
+
minLength: 1,
|
|
304
|
+
description:
|
|
305
|
+
"The name the domain is exported under in the symbol's source file, when the symbol's title is not that name.",
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
additionalProperties: false,
|
|
309
|
+
},
|
|
310
|
+
witness: {
|
|
311
|
+
type: "object",
|
|
312
|
+
description:
|
|
313
|
+
"typecheck: the repository-relative witness file Kibi compiles (an exhaustive switch ending in never, or a mapped type over the domain).",
|
|
314
|
+
required: ["path"],
|
|
315
|
+
properties: { path: { type: "string", minLength: 1 } },
|
|
316
|
+
additionalProperties: false,
|
|
317
|
+
},
|
|
318
|
+
proves: {
|
|
319
|
+
type: "array",
|
|
320
|
+
description:
|
|
321
|
+
"Certificate kinds: the requirement claim keys (CLAIM-...) this certificate proves. Each must be a modeled claim of a current requirement the test reaches through its scenarios. Kibi derives what the certificate must establish from the claim's grounding fact (a set fact for exhaustive or typecheck, a numeric fact for arithmetic or smt); a claim with no such derivation is only attested and never counts as proved.",
|
|
322
|
+
minItems: 1,
|
|
323
|
+
items: { type: "string", pattern: "^CLAIM-" },
|
|
324
|
+
uniqueItems: true,
|
|
325
|
+
},
|
|
326
|
+
value_source: {
|
|
327
|
+
type: "array",
|
|
328
|
+
description:
|
|
329
|
+
"arithmetic and smt: code constants the assumptions read. Kibi evaluates each export at ingest and requires the certificate to assume the variable equals that value, so the proof is about the code and not only the knowledge base.",
|
|
330
|
+
minItems: 1,
|
|
331
|
+
items: {
|
|
332
|
+
type: "object",
|
|
333
|
+
required: ["symbol_id"],
|
|
334
|
+
properties: {
|
|
335
|
+
symbol_id: { type: "string", minLength: 1 },
|
|
336
|
+
export: { type: "string", minLength: 1 },
|
|
337
|
+
},
|
|
338
|
+
additionalProperties: false,
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
constraint_source: {
|
|
342
|
+
type: "object",
|
|
343
|
+
description:
|
|
344
|
+
"arithmetic and smt: the typed numeric property_value facts the certificate's assumptions come from. Kibi checks the assumptions (or the query's assertions) are exactly these facts' constraints, so the proof is about the knowledge base, not numbers the test chose.",
|
|
345
|
+
required: ["fact_ids"],
|
|
346
|
+
properties: {
|
|
347
|
+
fact_ids: {
|
|
348
|
+
type: "array",
|
|
349
|
+
minItems: 1,
|
|
350
|
+
items: { type: "string", minLength: 1 },
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
additionalProperties: false,
|
|
354
|
+
},
|
|
221
355
|
},
|
|
222
356
|
additionalProperties: false,
|
|
223
357
|
} as const;
|
|
@@ -479,6 +613,24 @@ export function proofRunArtifactErrors(value: unknown): string[] {
|
|
|
479
613
|
)
|
|
480
614
|
errors.push("artifact.diagnostics must be an array of non-empty strings");
|
|
481
615
|
}
|
|
616
|
+
if (artifact.certificates !== undefined) {
|
|
617
|
+
if (!Array.isArray(artifact.certificates))
|
|
618
|
+
errors.push("artifact.certificates must be an array when present");
|
|
619
|
+
else
|
|
620
|
+
artifact.certificates.forEach((entry, index) => {
|
|
621
|
+
const row = record(entry);
|
|
622
|
+
if (
|
|
623
|
+
!row ||
|
|
624
|
+
!nonEmptyString(row.version) ||
|
|
625
|
+
!includes(CERTIFICATE_PROOF_KINDS, row.kind) ||
|
|
626
|
+
!nonEmptyString(row.test_id) ||
|
|
627
|
+
!isPlainJson(row)
|
|
628
|
+
)
|
|
629
|
+
errors.push(
|
|
630
|
+
`artifact.certificates[${index}] must be a JSON object with version, a certificate kind (${CERTIFICATE_PROOF_KINDS.join(", ")}) and test_id`,
|
|
631
|
+
);
|
|
632
|
+
});
|
|
633
|
+
}
|
|
482
634
|
return errors;
|
|
483
635
|
}
|
|
484
636
|
|
|
@@ -537,9 +689,172 @@ export function proofContractErrors(value: unknown): string[] {
|
|
|
537
689
|
errors.push(
|
|
538
690
|
`proof_contract.success_policy must be one of: ${SUCCESS_POLICIES.join(", ")}; received ${JSON.stringify(contract.success_policy ?? null)}`,
|
|
539
691
|
);
|
|
692
|
+
errors.push(...proofContractKindErrors(contract));
|
|
693
|
+
return errors;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// implements REQ-kibi-code-proof-kinds
|
|
697
|
+
function proofContractKindErrors(contract: Record<string, unknown>): string[] {
|
|
698
|
+
const errors: string[] = [];
|
|
699
|
+
const kind = contract.kind;
|
|
700
|
+
if (kind !== undefined && !includes(PROOF_KINDS, kind))
|
|
701
|
+
errors.push(
|
|
702
|
+
`proof_contract.kind must be one of: ${PROOF_KINDS.join(", ")}; received ${JSON.stringify(kind)}`,
|
|
703
|
+
);
|
|
704
|
+
const domain = contract.domain_source;
|
|
705
|
+
if (domain !== undefined) {
|
|
706
|
+
const row = record(domain);
|
|
707
|
+
if (
|
|
708
|
+
!row ||
|
|
709
|
+
!nonEmptyString(row.symbol_id) ||
|
|
710
|
+
(row.export !== undefined && !nonEmptyString(row.export)) ||
|
|
711
|
+
Object.keys(row).some((key) => key !== "symbol_id" && key !== "export")
|
|
712
|
+
)
|
|
713
|
+
errors.push(
|
|
714
|
+
"proof_contract.domain_source must be {symbol_id, export?} naming the symbol that defines the domain and, when its title is not the export name, the export to read",
|
|
715
|
+
);
|
|
716
|
+
} else if (kind === "exhaustive" || kind === "typecheck")
|
|
717
|
+
errors.push(
|
|
718
|
+
`proof_contract.domain_source is required for kind ${String(kind)}: name the symbol the proof reads its domain from`,
|
|
719
|
+
);
|
|
720
|
+
const witness = contract.witness;
|
|
721
|
+
if (witness !== undefined) {
|
|
722
|
+
const row = record(witness);
|
|
723
|
+
if (!row || !nonEmptyString(row.path) || Object.keys(row).length !== 1)
|
|
724
|
+
errors.push(
|
|
725
|
+
"proof_contract.witness must be {path} naming the repository-relative witness file",
|
|
726
|
+
);
|
|
727
|
+
} else if (kind === "typecheck")
|
|
728
|
+
errors.push(
|
|
729
|
+
"proof_contract.witness is required for kind typecheck: name the file the type checker compiles",
|
|
730
|
+
);
|
|
731
|
+
const source = contract.constraint_source;
|
|
732
|
+
if (source !== undefined) {
|
|
733
|
+
const row = record(source);
|
|
734
|
+
const ids = row?.fact_ids;
|
|
735
|
+
if (
|
|
736
|
+
!row ||
|
|
737
|
+
Object.keys(row).length !== 1 ||
|
|
738
|
+
!Array.isArray(ids) ||
|
|
739
|
+
ids.length === 0 ||
|
|
740
|
+
!ids.every(nonEmptyString)
|
|
741
|
+
)
|
|
742
|
+
errors.push(
|
|
743
|
+
"proof_contract.constraint_source must be {fact_ids: [FACT-...]} naming the facts the assumptions come from",
|
|
744
|
+
);
|
|
745
|
+
} else if (
|
|
746
|
+
(kind === "arithmetic" || kind === "smt") &&
|
|
747
|
+
contract.value_source === undefined
|
|
748
|
+
)
|
|
749
|
+
errors.push(
|
|
750
|
+
`proof_contract.constraint_source or value_source is required for kind ${String(kind)}: name the typed facts or code constants its assumptions come from`,
|
|
751
|
+
);
|
|
752
|
+
const valueSource = contract.value_source;
|
|
753
|
+
if (valueSource !== undefined) {
|
|
754
|
+
if (
|
|
755
|
+
!Array.isArray(valueSource) ||
|
|
756
|
+
valueSource.length === 0 ||
|
|
757
|
+
!valueSource.every((entry) => {
|
|
758
|
+
const row = record(entry);
|
|
759
|
+
return (
|
|
760
|
+
row !== null &&
|
|
761
|
+
nonEmptyString(row.symbol_id) &&
|
|
762
|
+
(row.export === undefined || nonEmptyString(row.export)) &&
|
|
763
|
+
Object.keys(row).every(
|
|
764
|
+
(key) => key === "symbol_id" || key === "export",
|
|
765
|
+
)
|
|
766
|
+
);
|
|
767
|
+
})
|
|
768
|
+
)
|
|
769
|
+
errors.push(
|
|
770
|
+
"proof_contract.value_source must be [{symbol_id, export?}] naming the code constants the assumptions read",
|
|
771
|
+
);
|
|
772
|
+
else if (kind !== "arithmetic" && kind !== "smt")
|
|
773
|
+
errors.push(
|
|
774
|
+
`proof_contract.value_source applies only to kind arithmetic or smt, not ${String(kind ?? "e2e")}`,
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
const proves = contract.proves;
|
|
778
|
+
if (proves !== undefined) {
|
|
779
|
+
if (
|
|
780
|
+
!Array.isArray(proves) ||
|
|
781
|
+
proves.length === 0 ||
|
|
782
|
+
!proves.every(
|
|
783
|
+
(key) => typeof key === "string" && /^CLAIM-[A-Za-z0-9]+$/.test(key),
|
|
784
|
+
) ||
|
|
785
|
+
new Set(proves).size !== proves.length
|
|
786
|
+
)
|
|
787
|
+
errors.push(
|
|
788
|
+
"proof_contract.proves must be a non-empty list of distinct claim keys (CLAIM-...) the certificate proves",
|
|
789
|
+
);
|
|
790
|
+
else if (!isCertificateProofKind(kind))
|
|
791
|
+
errors.push(
|
|
792
|
+
`proof_contract.proves applies only to certificate kinds (exhaustive, typecheck, arithmetic, smt), not ${String(kind ?? "e2e")}`,
|
|
793
|
+
);
|
|
794
|
+
}
|
|
540
795
|
return errors;
|
|
541
796
|
}
|
|
542
797
|
|
|
798
|
+
/**
|
|
799
|
+
* The optional contract fields beyond the v1 core, copied only when present
|
|
800
|
+
* so existing contracts keep their hash.
|
|
801
|
+
*/
|
|
802
|
+
// implements REQ-kibi-code-proof-kinds
|
|
803
|
+
export function optionalProofContractFields(
|
|
804
|
+
contract: Record<string, unknown>,
|
|
805
|
+
): Pick<
|
|
806
|
+
ProofContract,
|
|
807
|
+
| "kind"
|
|
808
|
+
| "domain_source"
|
|
809
|
+
| "witness"
|
|
810
|
+
| "constraint_source"
|
|
811
|
+
| "value_source"
|
|
812
|
+
| "proves"
|
|
813
|
+
> {
|
|
814
|
+
const fields: {
|
|
815
|
+
kind?: ProofKind;
|
|
816
|
+
domain_source?: { symbol_id: string; export?: string };
|
|
817
|
+
witness?: { path: string };
|
|
818
|
+
constraint_source?: { fact_ids: string[] };
|
|
819
|
+
value_source?: { symbol_id: string; export?: string }[];
|
|
820
|
+
proves?: string[];
|
|
821
|
+
} = {};
|
|
822
|
+
if (typeof contract.kind === "string")
|
|
823
|
+
fields.kind = contract.kind as ProofKind;
|
|
824
|
+
const domain = record(contract.domain_source);
|
|
825
|
+
if (domain && typeof domain.symbol_id === "string")
|
|
826
|
+
fields.domain_source = {
|
|
827
|
+
symbol_id: domain.symbol_id,
|
|
828
|
+
...(typeof domain.export === "string" ? { export: domain.export } : {}),
|
|
829
|
+
};
|
|
830
|
+
const witness = record(contract.witness);
|
|
831
|
+
if (witness && typeof witness.path === "string")
|
|
832
|
+
fields.witness = { path: witness.path };
|
|
833
|
+
const source = record(contract.constraint_source);
|
|
834
|
+
if (source && Array.isArray(source.fact_ids))
|
|
835
|
+
fields.constraint_source = {
|
|
836
|
+
fact_ids: source.fact_ids.filter(
|
|
837
|
+
(id): id is string => typeof id === "string",
|
|
838
|
+
),
|
|
839
|
+
};
|
|
840
|
+
if (Array.isArray(contract.value_source))
|
|
841
|
+
fields.value_source = contract.value_source
|
|
842
|
+
.map((entry) => record(entry))
|
|
843
|
+
.filter(
|
|
844
|
+
(row): row is Record<string, unknown> =>
|
|
845
|
+
row !== null && typeof row.symbol_id === "string",
|
|
846
|
+
)
|
|
847
|
+
.map((row) => ({
|
|
848
|
+
symbol_id: String(row.symbol_id),
|
|
849
|
+
...(typeof row.export === "string" ? { export: row.export } : {}),
|
|
850
|
+
}));
|
|
851
|
+
if (Array.isArray(contract.proves))
|
|
852
|
+
fields.proves = contract.proves.filter(
|
|
853
|
+
(key): key is string => typeof key === "string",
|
|
854
|
+
);
|
|
855
|
+
return fields;
|
|
856
|
+
}
|
|
857
|
+
|
|
543
858
|
export function proofBindingsErrors(value: unknown): string[] {
|
|
544
859
|
if (!Array.isArray(value))
|
|
545
860
|
return ["proof_bindings must be an array of binding objects"];
|
|
@@ -4,14 +4,33 @@ import {
|
|
|
4
4
|
proofContractHash,
|
|
5
5
|
} from "./proof-fingerprint.js";
|
|
6
6
|
import {
|
|
7
|
+
PROOF_KINDS,
|
|
7
8
|
PROOF_RECEIPT_VERSION,
|
|
9
|
+
PROOF_RECEIPT_VERSIONS,
|
|
8
10
|
PROOF_RESULT_OUTCOMES,
|
|
9
11
|
PROOF_RUN_OUTCOMES,
|
|
10
12
|
type ProofContract,
|
|
13
|
+
type ProofKind,
|
|
14
|
+
isCertificateProofKind,
|
|
11
15
|
} from "./proof-protocol.js";
|
|
12
16
|
|
|
13
17
|
export const PROOF_RECEIPT_MAX_AGE_SECONDS = 7 * 24 * 60 * 60;
|
|
14
18
|
|
|
19
|
+
/**
|
|
20
|
+
* How a certificate binds to a claim its contract names in proves: derived
|
|
21
|
+
* (Kibi checked it against the claim's fact; the only verdict that proves),
|
|
22
|
+
* attested (the fact has no derivation; the author vouches) or rejected.
|
|
23
|
+
*/
|
|
24
|
+
// implements REQ-kibi-claim-bound-proofs
|
|
25
|
+
export const CLAIM_BINDING_VERDICTS = [
|
|
26
|
+
"derived",
|
|
27
|
+
"attested",
|
|
28
|
+
"rejected",
|
|
29
|
+
] as const;
|
|
30
|
+
|
|
31
|
+
// implements REQ-kibi-claim-bound-proofs
|
|
32
|
+
export type ClaimBindingVerdict = (typeof CLAIM_BINDING_VERDICTS)[number];
|
|
33
|
+
|
|
15
34
|
export const PROOF_RECEIPT_OUTCOMES = [
|
|
16
35
|
"passed",
|
|
17
36
|
"failed",
|
|
@@ -25,7 +44,7 @@ export const PROOF_RECEIPT_OUTCOMES = [
|
|
|
25
44
|
export const PROOF_RECEIPT_SCHEMA = {
|
|
26
45
|
type: "object",
|
|
27
46
|
description:
|
|
28
|
-
"Kibi-derived kibi.proof-receipt.v1. Receipts are never caller-authored; kb_ingest_proof derives them from kibi.proof-run.v1 artifacts.",
|
|
47
|
+
"Kibi-derived kibi.proof-receipt.v2 (kibi.proof-receipt.v1 entries are still read). Receipts are never caller-authored; kb_ingest_proof derives them from kibi.proof-run.v1 artifacts.",
|
|
29
48
|
required: [
|
|
30
49
|
"version",
|
|
31
50
|
"receipt_id",
|
|
@@ -47,7 +66,7 @@ export const PROOF_RECEIPT_SCHEMA = {
|
|
|
47
66
|
"proof_results",
|
|
48
67
|
],
|
|
49
68
|
properties: {
|
|
50
|
-
version: { type: "string",
|
|
69
|
+
version: { type: "string", enum: [...PROOF_RECEIPT_VERSIONS] },
|
|
51
70
|
receipt_id: {
|
|
52
71
|
type: "string",
|
|
53
72
|
pattern: "^PR-[A-Za-z0-9][A-Za-z0-9._:-]{7,127}$",
|
|
@@ -144,6 +163,33 @@ export const PROOF_RECEIPT_SCHEMA = {
|
|
|
144
163
|
additionalProperties: false,
|
|
145
164
|
},
|
|
146
165
|
},
|
|
166
|
+
kind: { type: "string", enum: [...PROOF_KINDS] },
|
|
167
|
+
evidence_level: { type: "string", enum: ["proved", "tested"] },
|
|
168
|
+
certificate: { type: "object" },
|
|
169
|
+
certificate_digest: { type: "string", pattern: "^[a-f0-9]{64}$" },
|
|
170
|
+
certificate_rejection: { type: "string", minLength: 1 },
|
|
171
|
+
claim_bindings: {
|
|
172
|
+
type: "array",
|
|
173
|
+
description:
|
|
174
|
+
"Certificate kinds: how the certificate binds to each claim its contract names in proves, judged at ingest. derived means Kibi derived the certificate's obligation from the claim's grounding fact and the certificate satisfies it; attested means no derivation exists and the author vouches for it (never proved); rejected names why.",
|
|
175
|
+
items: {
|
|
176
|
+
type: "object",
|
|
177
|
+
required: ["claim_key", "binding"],
|
|
178
|
+
properties: {
|
|
179
|
+
claim_key: { type: "string", minLength: 1 },
|
|
180
|
+
requirement_id: { type: "string", minLength: 1 },
|
|
181
|
+
fact_id: { type: "string", minLength: 1 },
|
|
182
|
+
binding: {
|
|
183
|
+
type: "string",
|
|
184
|
+
enum: [...CLAIM_BINDING_VERDICTS],
|
|
185
|
+
},
|
|
186
|
+
scope: { type: "string", enum: ["code", "intent"] },
|
|
187
|
+
obligation: { type: "object" },
|
|
188
|
+
reason: { type: "string", minLength: 1 },
|
|
189
|
+
},
|
|
190
|
+
additionalProperties: false,
|
|
191
|
+
},
|
|
192
|
+
},
|
|
147
193
|
gaps: {
|
|
148
194
|
type: "array",
|
|
149
195
|
items: {
|
|
@@ -162,7 +208,7 @@ export const PROOF_RECEIPT_SCHEMA = {
|
|
|
162
208
|
} as const;
|
|
163
209
|
|
|
164
210
|
export type ProofReceipt = Readonly<{
|
|
165
|
-
version: typeof
|
|
211
|
+
version: (typeof PROOF_RECEIPT_VERSIONS)[number];
|
|
166
212
|
receipt_id: string;
|
|
167
213
|
test_id: string;
|
|
168
214
|
scope: "unit" | "integration" | "end_to_end";
|
|
@@ -201,6 +247,27 @@ export type ProofReceipt = Readonly<{
|
|
|
201
247
|
readonly target: string;
|
|
202
248
|
readonly reason: string;
|
|
203
249
|
}[];
|
|
250
|
+
/** v2: what the contract's checker establishes. */
|
|
251
|
+
kind?: ProofKind;
|
|
252
|
+
/** v2: proved only for a passed certificate kind whose certificate re-checked. */
|
|
253
|
+
evidence_level?: "proved" | "tested";
|
|
254
|
+
certificate?: Readonly<Record<string, unknown>>;
|
|
255
|
+
certificate_digest?: string;
|
|
256
|
+
certificate_rejection?: string;
|
|
257
|
+
/** Certificate kinds: the binding to each claim the contract names in proves. */
|
|
258
|
+
claim_bindings?: readonly ClaimBinding[];
|
|
259
|
+
}>;
|
|
260
|
+
|
|
261
|
+
/** How one certificate binds to one requirement claim, judged at ingest. */
|
|
262
|
+
// implements REQ-kibi-claim-bound-proofs
|
|
263
|
+
export type ClaimBinding = Readonly<{
|
|
264
|
+
claim_key: string;
|
|
265
|
+
requirement_id?: string;
|
|
266
|
+
fact_id?: string;
|
|
267
|
+
binding: ClaimBindingVerdict;
|
|
268
|
+
scope?: "code" | "intent";
|
|
269
|
+
obligation?: Readonly<Record<string, unknown>>;
|
|
270
|
+
reason?: string;
|
|
204
271
|
}>;
|
|
205
272
|
|
|
206
273
|
export function finishedAtPrecedesStartedAt(
|
|
@@ -285,14 +352,17 @@ function validFingerprintComponents(value: unknown): boolean {
|
|
|
285
352
|
);
|
|
286
353
|
}
|
|
287
354
|
|
|
288
|
-
/** Structural validation of one kibi.proof-receipt.v1 entry. */
|
|
355
|
+
/** Structural validation of one kibi.proof-receipt.v1 or v2 entry. */
|
|
289
356
|
export function validProofReceiptShape(
|
|
290
357
|
testId: string,
|
|
291
358
|
receipt: unknown,
|
|
292
359
|
): boolean {
|
|
293
360
|
const row = isRecord(receipt) ? receipt : null;
|
|
294
361
|
if (!row) return false;
|
|
295
|
-
if (row.version
|
|
362
|
+
if (!(PROOF_RECEIPT_VERSIONS as readonly unknown[]).includes(row.version))
|
|
363
|
+
return false;
|
|
364
|
+
if (row.version === PROOF_RECEIPT_VERSION && !validV2Fields(row))
|
|
365
|
+
return false;
|
|
296
366
|
if (
|
|
297
367
|
typeof row.receipt_id !== "string" ||
|
|
298
368
|
!/^PR-[A-Za-z0-9][A-Za-z0-9._:-]{7,127}$/.test(row.receipt_id)
|
|
@@ -358,9 +428,59 @@ export function validProofReceiptShape(
|
|
|
358
428
|
return !finishedAtPrecedesStartedAt(startedAt, finishedAt);
|
|
359
429
|
}
|
|
360
430
|
|
|
431
|
+
// implements REQ-kibi-code-proof-kinds
|
|
432
|
+
function validV2Fields(row: Record<string, unknown>): boolean {
|
|
433
|
+
if (!(PROOF_KINDS as readonly unknown[]).includes(row.kind)) return false;
|
|
434
|
+
if (row.evidence_level !== "proved" && row.evidence_level !== "tested")
|
|
435
|
+
return false;
|
|
436
|
+
if (
|
|
437
|
+
row.evidence_level === "proved" &&
|
|
438
|
+
(row.outcome !== "passed" ||
|
|
439
|
+
!isCertificateProofKind(row.kind) ||
|
|
440
|
+
!isRecord(row.certificate) ||
|
|
441
|
+
!hex64(row.certificate_digest) ||
|
|
442
|
+
row.certificate_rejection !== undefined)
|
|
443
|
+
)
|
|
444
|
+
return false;
|
|
445
|
+
if (row.certificate !== undefined && !isRecord(row.certificate)) return false;
|
|
446
|
+
if (row.certificate_digest !== undefined && !hex64(row.certificate_digest))
|
|
447
|
+
return false;
|
|
448
|
+
if (
|
|
449
|
+
row.certificate_rejection !== undefined &&
|
|
450
|
+
!nonEmptyString(row.certificate_rejection)
|
|
451
|
+
)
|
|
452
|
+
return false;
|
|
453
|
+
if (
|
|
454
|
+
row.claim_bindings !== undefined &&
|
|
455
|
+
!validClaimBindings(row.claim_bindings)
|
|
456
|
+
)
|
|
457
|
+
return false;
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// implements REQ-kibi-claim-bound-proofs
|
|
462
|
+
function validClaimBindings(value: unknown): boolean {
|
|
463
|
+
return (
|
|
464
|
+
Array.isArray(value) &&
|
|
465
|
+
value.every(
|
|
466
|
+
(entry) =>
|
|
467
|
+
isRecord(entry) &&
|
|
468
|
+
nonEmptyString(entry.claim_key) &&
|
|
469
|
+
(CLAIM_BINDING_VERDICTS as readonly unknown[]).includes(
|
|
470
|
+
entry.binding,
|
|
471
|
+
) &&
|
|
472
|
+
(entry.scope === undefined ||
|
|
473
|
+
entry.scope === "code" ||
|
|
474
|
+
entry.scope === "intent") &&
|
|
475
|
+
(entry.obligation === undefined || isRecord(entry.obligation)) &&
|
|
476
|
+
(entry.reason === undefined || nonEmptyString(entry.reason)),
|
|
477
|
+
)
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
|
|
361
481
|
/**
|
|
362
482
|
* Full-history validation for proof_receipts: unique ids, per-test binding,
|
|
363
|
-
* supported scope, ordered timestamps, and structurally valid v1 entries.
|
|
483
|
+
* supported scope, ordered timestamps, and structurally valid v1 or v2 entries.
|
|
364
484
|
*/
|
|
365
485
|
export function proofReceiptHistoryErrors(
|
|
366
486
|
testId: string,
|
|
@@ -388,7 +508,7 @@ export function proofReceiptHistoryErrors(
|
|
|
388
508
|
}
|
|
389
509
|
if (!validProofReceiptShape(testId, receipt)) {
|
|
390
510
|
errors.push(
|
|
391
|
-
`${prefix} must be a structurally valid kibi.proof-receipt.v1 bound to '${testId}'`,
|
|
511
|
+
`${prefix} must be a structurally valid kibi.proof-receipt.v2 (or v1) bound to '${testId}'`,
|
|
392
512
|
);
|
|
393
513
|
continue;
|
|
394
514
|
}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { ENTITY_ORIGIN_SCHEMA } from "../entity-origin.js";
|
|
20
|
+
import { EVIDENCE_LEVELS } from "../evidence-levels.js";
|
|
20
21
|
import {
|
|
21
22
|
PROOF_BINDINGS_SCHEMA,
|
|
22
23
|
PROOF_CONTRACT_SCHEMA,
|
|
@@ -364,6 +365,12 @@ const entitySchema: Record<string, unknown> = {
|
|
|
364
365
|
description:
|
|
365
366
|
"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: a delegated or agent choice; a later agent may supersede it with evidence. exploratory: a flagged guess, expected to be revisited. When absent, it reads as default if an agent wrote the entity (origin.kind agent) and as firm otherwise (a person's, imported or migrated decision); set it explicitly when recording a decision.",
|
|
366
367
|
},
|
|
368
|
+
required_evidence: {
|
|
369
|
+
type: "string",
|
|
370
|
+
enum: [...EVIDENCE_LEVELS],
|
|
371
|
+
description:
|
|
372
|
+
"Requirement-only. The weakest evidence level this current requirement accepts; the evidence-floor check rule fails while its computed evidence level is lower. proved: a re-checkable certificate covers every case. tested: fresh passing E2E receipts cover every linked scenario. asserted: a person stands behind it. unverified: no floor. When absent, it is tested for a firm requirement and unverified otherwise.",
|
|
373
|
+
},
|
|
367
374
|
expects: {
|
|
368
375
|
type: "string",
|
|
369
376
|
enum: ["success", "rejection", "error"],
|
|
@@ -543,8 +550,17 @@ const entitySchema: Record<string, unknown> = {
|
|
|
543
550
|
subject_key: { type: "string" },
|
|
544
551
|
property_key: { type: "string" },
|
|
545
552
|
operator: { type: "string", enum: ["eq", "neq", "lt", "lte", "gt", "gte"] },
|
|
546
|
-
value_type: {
|
|
553
|
+
value_type: {
|
|
554
|
+
type: "string",
|
|
555
|
+
enum: ["string", "int", "number", "bool", "set"],
|
|
556
|
+
},
|
|
547
557
|
value_string: { type: "string" },
|
|
558
|
+
value_set: {
|
|
559
|
+
type: "array",
|
|
560
|
+
items: { type: "string", minLength: 1 },
|
|
561
|
+
minItems: 1,
|
|
562
|
+
uniqueItems: true,
|
|
563
|
+
},
|
|
548
564
|
value_int: { type: "integer" },
|
|
549
565
|
value_number: { type: "number" },
|
|
550
566
|
value_bool: { type: "boolean" },
|
|
@@ -643,6 +659,7 @@ const entitySchema: Record<string, unknown> = {
|
|
|
643
659
|
{ required: ["value_int"] },
|
|
644
660
|
{ required: ["value_number"] },
|
|
645
661
|
{ required: ["value_bool"] },
|
|
662
|
+
{ required: ["value_set"] },
|
|
646
663
|
{ required: ["unit"] },
|
|
647
664
|
{ required: ["scope"] },
|
|
648
665
|
{ required: ["polarity"] },
|
|
@@ -715,6 +732,7 @@ const entitySchema: Record<string, unknown> = {
|
|
|
715
732
|
{ required: ["approval_ref"] },
|
|
716
733
|
{ required: ["rationale"] },
|
|
717
734
|
{ required: ["exempts_claims"] },
|
|
735
|
+
{ required: ["required_evidence"] },
|
|
718
736
|
],
|
|
719
737
|
},
|
|
720
738
|
},
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-bootstrap
|
|
3
3
|
name: kibi-bootstrap
|
|
4
4
|
description: "Use for any Kibi bootstrap or onboarding task: seeding a new or thin knowledge base; reviewing a bootstrap or onboarding plan, preview, or evidence; judging approval readiness or coverage; diagnosing a blocked, partial, or failed bootstrap or its repair; applying an approved bootstrap plan; or asking the human which knowledge sources hold intent. Covers kb_status first, source interview, cited intent claims, read-only kb_plan_bootstrap preview, explicit approval, exact-plan kb_apply_plan, and repair-safe close-out."
|
|
5
|
-
version: 3.
|
|
5
|
+
version: 3.17.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -43,7 +43,7 @@ Seed branch-local Kibi knowledge from cited product intent, without creating a p
|
|
|
43
43
|
9. **Read back** with `kb_query` and `kb_search` to confirm writes and citations.
|
|
44
44
|
10. **Close out** with `kb_check`, then `kb_status`.
|
|
45
45
|
11. **Deepen.** Bootstrap is complete; the KB is now half-way, holding cited `req` entries and review facts but no scenarios, tests or predicates. Load `kibi-usage` and continue in the normal Kibi workflow, one area at a time, telling the human what you author:
|
|
46
|
-
- **Unplanned claims.** For every claim suppressed as `invalid_write` and every `sourceOnlySignals` entry ("Author requirement …"), restate the claim's statement and citation (`sourceId:reference`), model it with `kb_model` (`mode: "requirement"`, or `mode: "predicates"` for domain claims), and write the result with `kb_upsert` (`dryRun: true` first) with `origin: {kind: "import", ref: "<sourceId:reference>"}` and `firmness: "firm"`, as the plan does for the claims it writes. Without an explicit origin `kb_upsert` records the requirement as the agent's own `default` choice, which a later agent may supersede without asking.
|
|
46
|
+
- **Unplanned claims.** For every claim suppressed as `invalid_write` and every `sourceOnlySignals` entry ("Author requirement …"), restate the claim's statement and citation (`sourceId:reference`), model it with `kb_model` (`mode: "requirement"`, or `mode: "predicates"` for domain claims), and write the result with `kb_upsert` (`dryRun: true` first) with `origin: {kind: "import", ref: "<sourceId:reference>"}` and `firmness: "firm"` and `required_evidence: "asserted"`, as the plan does for the claims it writes; raise the floor (drop `required_evidence`) only once an end-to-end proof covers the requirement. Without an explicit origin `kb_upsert` records the requirement as the agent's own `default` choice, which a later agent may supersede without asking.
|
|
47
47
|
- **Scenarios.** Write scenarios from the cited ticket's acceptance criteria, one scenario per criterion, not bulk drafts from the requirement title; ask the human when the source states none. Give each a plain title, the scenario prose in `document.body` (never in `properties`), and `assumes` links to the `property_value` facts whose values the scenario relies on. Set `expects` only when the scenario links `assumes` facts (or its criterion names concrete values that become them); `expects` without `assumes` only yields a feasibility-unknown warning, so a draft tagged `needs-human-review` omits `expects`. Then link the requirement with `specified_by` (upsert the `req` with its stored `title`, a `status` and that relationship only). Example: criterion "Given an annotation in draft state, when the user deletes it, the draft is cleared" becomes `{"type":"scenario","id":"SCEN-annotation-delete-clears-draft","properties":{"title":"Deleting a draft annotation clears the draft","status":"active","expects":"success"},"document":{"body":"Given an annotation in draft state, when the user deletes it, then the draft is cleared and nothing is published.\n\nThe acceptance criterion comes from the cited ticket; reviewers asked for it so a deleted draft never reappears after reload.\n"},"relationships":[{"type":"assumes","from":"SCEN-annotation-delete-clears-draft","to":"FACT-annotation-state-draft"}]}`, where the assumed fact is a `property_value` (`annotation.state` `eq` `draft`). Link existing tests that exercise it; never invent test evidence.
|
|
48
48
|
- **Predicates.** Run `kb_model` with `mode: "predicates"` and `requirementId` on each persisted requirement and apply a returned plan with `requires_predicate` to its `relationshipTarget` (the planned `FACT-PRED-…` id, never a `SUGGEST-…` candidate id), or record the `review:ontology-gap` observation it returns, with its prose in `document.body`. A non-empty `existingGrounding` means the bootstrap already grounded that claim: on `replace_grounding` leave it unless the human wants the `replacementPlan` swap; on `provide_argument_bindings` retry with the listed arguments bound; on `record_ontology_gap` still write the returned gap observation, which is not a grounding link. Count what `kb_query` shows afterwards, not the calls you made.
|
|
49
49
|
- **Unrecorded ambiguity.** Record any conflict or open question you found but did not declare in step 3 as a cited `fact_kind: observation` tagged `review:conflict` or `review:open-question`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-commit-review
|
|
3
3
|
name: kibi-commit-review
|
|
4
4
|
description: "Use when kibi check --staged or the Kibi pre-commit hook blocks a commit (kibi_impact_evidence_missing, symbols_manifest_stale, symbol_granularity_violation, symbol-coverage, kibi check-generated drift, Staged impact review failed), or when preparing a commit or pull-request impact review. Covers reading the per-file Detail lines, authoring .kb/symbols.yaml symbol entries through kb_upsert, kibi sync --refresh-symbol-coordinates, staging the tracked Kibi evidence with git add, kb_prepare_impact_review for a staged or diff scope, the kibi signoff requirements summary to show before a commit, and how merge commits and migration renames are judged."
|
|
5
|
-
version: 1.2.
|
|
5
|
+
version: 1.2.2
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|