kibi-cli 2.30.0 → 2.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-operation-metadata.d.ts +1 -1
- package/dist/cli-operation-metadata.js +1 -1
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +23 -2
- package/dist/commands/check-certificates.d.ts +52 -0
- package/dist/commands/check-certificates.d.ts.map +1 -0
- package/dist/commands/check-certificates.js +163 -0
- package/dist/commands/discovery-table.d.ts.map +1 -1
- package/dist/commands/discovery-table.js +14 -2
- package/dist/commands/report.js +3 -3
- package/dist/commands/signoff.d.ts.map +1 -1
- package/dist/commands/signoff.js +4 -1
- package/dist/operations/planning/apply-plan.js +5 -5
- package/dist/operations/proof/baseline-diff.d.ts +1 -1
- package/dist/operations/proof/baseline-diff.js +1 -1
- package/dist/operations/proof/impact.d.ts +10 -4
- package/dist/operations/proof/impact.d.ts.map +1 -1
- package/dist/operations/proof/impact.js +27 -7
- package/dist/public/diagnostic-usage.js +2 -2
- package/dist/public/operations/catalog.d.ts +4 -4
- 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/reporting.d.ts +4 -4
- package/dist/public/operations/specs/reporting.js +7 -7
- package/dist/public/skills/kibi-commit-review/SKILL.md +4 -3
- package/dist/public/skills/kibi-decisions/SKILL.md +1 -1
- package/dist/public/skills/kibi-decisions/resources/signoff-views.md +3 -2
- package/dist/public/skills/kibi-freshness/SKILL.md +2 -2
- package/dist/public/skills/kibi-usage/SKILL.md +2 -2
- package/dist/public/skills/kibi-usage/resources/proof.md +36 -4
- package/dist/public/skills/kibi-usage/resources/workflows.md +1 -1
- package/dist/report/html-report.css +11 -4
- package/dist/report/html-report.d.ts +2 -2
- package/dist/report/html-report.d.ts.map +1 -1
- package/dist/report/html-report.js +27 -21
- package/dist/report/report-view.d.ts +2 -2
- package/dist/report/report-view.js +2 -2
- package/dist/signoff/collect.d.ts.map +1 -1
- package/dist/signoff/collect.js +5 -1
- package/dist/signoff/html.js +3 -3
- package/dist/signoff/model.d.ts +7 -2
- package/dist/signoff/model.d.ts.map +1 -1
- package/dist/signoff/model.js +6 -2
- package/dist/traceability/staged-consistency.d.ts.map +1 -1
- package/dist/traceability/staged-consistency.js +3 -1
- 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/package.json +2 -2
- package/src/public/diagnostic-usage.ts +3 -3
- package/src/public/operations/specs/check-rules.generated.ts +3 -1
- package/src/public/operations/specs/reporting.ts +7 -7
- package/src/public/skills/kibi-commit-review/SKILL.md +4 -3
- package/src/public/skills/kibi-decisions/SKILL.md +1 -1
- package/src/public/skills/kibi-decisions/resources/signoff-views.md +3 -2
- package/src/public/skills/kibi-freshness/SKILL.md +2 -2
- package/src/public/skills/kibi-usage/SKILL.md +2 -2
- package/src/public/skills/kibi-usage/resources/proof.md +36 -4
- package/src/public/skills/kibi-usage/resources/workflows.md +1 -1
- package/templates/github/kibi-badge.yml +1 -1
|
@@ -62,7 +62,9 @@ export const SELECTABLE_RULE_NAMES = [
|
|
|
62
62
|
"supersedes-reason-acknowledged",
|
|
63
63
|
"policy-ownership",
|
|
64
64
|
"policy-markers",
|
|
65
|
+
"kb-consistency",
|
|
66
|
+
"kb-consistency-unresolved",
|
|
65
67
|
];
|
|
66
68
|
// implements REQ-006
|
|
67
69
|
/** Comma-separated "Allowed:" fragment for the kb_check rules description. */
|
|
68
|
-
export const SELECTABLE_RULES_ALLOWED = "must-priority-coverage, symbol-coverage, symbol-traceability, symbol-granularity, no-dangling-refs, source-relationship-parity, branch-store-not-compiled, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, decision-firm-unreferenced, decision-firm-superseded, decision-firm-edited, supersedes-reason-missing, supersedes-reason-acknowledged, policy-ownership, policy-markers";
|
|
70
|
+
export const SELECTABLE_RULES_ALLOWED = "must-priority-coverage, symbol-coverage, symbol-traceability, symbol-granularity, no-dangling-refs, source-relationship-parity, branch-store-not-compiled, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, decision-firm-unreferenced, decision-firm-superseded, decision-firm-edited, supersedes-reason-missing, supersedes-reason-acknowledged, policy-ownership, policy-markers, kb-consistency, kb-consistency-unresolved";
|
|
@@ -12,7 +12,7 @@ export declare const checkSpec: {
|
|
|
12
12
|
readonly type: "string";
|
|
13
13
|
readonly enum: readonly string[];
|
|
14
14
|
};
|
|
15
|
-
readonly description: "Optional rule subset. Allowed: must-priority-coverage, symbol-coverage, symbol-traceability, symbol-granularity, no-dangling-refs, source-relationship-parity, branch-store-not-compiled, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, decision-firm-unreferenced, decision-firm-superseded, decision-firm-edited, supersedes-reason-missing, supersedes-reason-acknowledged, policy-ownership, policy-markers. If omitted, server runs canonical and advisory rules plus the full-KB qualityDiagnostics audit scan, including usage telemetry acceptance when evidence exists; migration rules run only when explicitly selected. Advisory and migration findings are non-blocking qualityDiagnostics. If supplied, server preserves scoped validation and skips the full-KB advisory scan.";
|
|
15
|
+
readonly description: "Optional rule subset. Allowed: must-priority-coverage, symbol-coverage, symbol-traceability, symbol-granularity, no-dangling-refs, source-relationship-parity, branch-store-not-compiled, source-path-dangling, no-cycles, required-fields, deprecated-adr-no-successor, superseded-requirement-open, scenario-feasibility, scenario-feasibility-unknown, exception-claim-keys, numeric-string-value, rule-key-arguments-missing, domain-contradictions, logic-coverage, rule-safety, rule-verifiability, query-plan-safety, req-status-vocabulary, strict-fact-shape, strict-req-fact-pairing, predicate-verifiability, strict-readiness, semantic-completeness, related-requirement-unmodeled, proof-contract-symbols, entity-id-style, domain-redundancy, domain-implication, subject-key-identity, subject-key-shape, ontology-quality, exception-unapproved, exception-approval-self-attested, agent-requirement-unapproved, requirement-rationale-missing, symbol-owner-superseded, adr-unlinked, adr-proposed, predicate-schema-conformance, entity-context-missing, entity-context-acknowledged, decision-firm-unreferenced, decision-firm-superseded, decision-firm-edited, supersedes-reason-missing, supersedes-reason-acknowledged, policy-ownership, policy-markers, kb-consistency, kb-consistency-unresolved. If omitted, server runs canonical and advisory rules plus the full-KB qualityDiagnostics audit scan, including usage telemetry acceptance when evidence exists; migration rules run only when explicitly selected. Advisory and migration findings are non-blocking qualityDiagnostics. If supplied, server preserves scoped validation and skips the full-KB advisory scan.";
|
|
16
16
|
};
|
|
17
17
|
readonly sourceFiles: {
|
|
18
18
|
readonly type: "array";
|
|
@@ -125,7 +125,7 @@ export declare const findGapsSpec: {
|
|
|
125
125
|
* + bound-symbol code scope) and hand the Prolog coverage stage a
|
|
126
126
|
* TestId -> BindingHash dict. This is the default binding mode since slice 3;
|
|
127
127
|
* KIBI_PROOF_BINDING_MODE=strict-snapshot opts out (receipts then match only
|
|
128
|
-
* against the whole-workspace snapshot they were
|
|
128
|
+
* against the whole-workspace snapshot they were produced on).
|
|
129
129
|
*/
|
|
130
130
|
export declare function currentProofBindingMode(): "per_contract" | "strict_snapshot";
|
|
131
131
|
export declare function perContractTestBindings(context: OperationContext): Promise<string | null>;
|
|
@@ -141,7 +141,7 @@ export declare function executeCoverage(input: CoverageInput, context: Operation
|
|
|
141
141
|
export declare const coverageSpec: {
|
|
142
142
|
readonly name: "kb_coverage";
|
|
143
143
|
readonly cliName: "coverage";
|
|
144
|
-
readonly description: "Generate curated structural coverage and conservative end-to-end requirement proof reports for requirements, symbols, or grouped types. Use it to ask which requirements are
|
|
144
|
+
readonly description: "Generate curated structural coverage and conservative end-to-end requirement proof reports for requirements, symbols, or grouped types. Use it to ask which requirements are tested end to end, how strong each requirement's evidence is (evidenceLevel: proved, tested, asserted or unverified), and what blocks the rest; use kb_find_gaps for a plain list of missing links and kb_check for rule violations. Reports include the compatible repair plan plus typed kibi.migration-plan.v2 actions; semantic and E2E actions remain review/execution work. Paginated plans identify incomplete scope and no mutation occurs.";
|
|
145
145
|
readonly businessInputSchema: {
|
|
146
146
|
readonly type: "object";
|
|
147
147
|
readonly properties: {
|
|
@@ -161,13 +161,13 @@ export declare const coverageSpec: {
|
|
|
161
161
|
readonly includePassing: {
|
|
162
162
|
readonly type: "boolean";
|
|
163
163
|
readonly default: false;
|
|
164
|
-
readonly description: "Also return rows that are already
|
|
164
|
+
readonly description: "Also return rows that are already tested or not applicable. By default only rows that still need repair are returned.";
|
|
165
165
|
};
|
|
166
166
|
readonly statuses: {
|
|
167
167
|
readonly type: "array";
|
|
168
168
|
readonly items: {
|
|
169
169
|
readonly type: "string";
|
|
170
|
-
readonly enum: readonly ["
|
|
170
|
+
readonly enum: readonly ["tested", "missing", "unresolved", "not_applicable"];
|
|
171
171
|
};
|
|
172
172
|
readonly description: "Requirement proof-status filter (req mode): include only rows whose proofStatus is listed. Selecting statuses implies include-passing; not_applicable rows carry their typed applicability reason in proofStages.applicability.reason. The summary always reflects the whole KB.";
|
|
173
173
|
};
|
|
@@ -30,7 +30,7 @@ function validateEntityType(type) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
const COVERAGE_PROOF_STATUSES = new Set([
|
|
33
|
-
"
|
|
33
|
+
"tested",
|
|
34
34
|
"missing",
|
|
35
35
|
"unresolved",
|
|
36
36
|
"not_applicable",
|
|
@@ -120,7 +120,7 @@ export const findGapsSpec = {
|
|
|
120
120
|
* + bound-symbol code scope) and hand the Prolog coverage stage a
|
|
121
121
|
* TestId -> BindingHash dict. This is the default binding mode since slice 3;
|
|
122
122
|
* KIBI_PROOF_BINDING_MODE=strict-snapshot opts out (receipts then match only
|
|
123
|
-
* against the whole-workspace snapshot they were
|
|
123
|
+
* against the whole-workspace snapshot they were produced on).
|
|
124
124
|
*/
|
|
125
125
|
// implements REQ-kibi-verification-evidence-contract
|
|
126
126
|
export function currentProofBindingMode() {
|
|
@@ -286,13 +286,13 @@ export async function executeCoverage(input, context) {
|
|
|
286
286
|
},
|
|
287
287
|
};
|
|
288
288
|
const fullyCovered = Number(enrichedPayload.summary?.fullyCovered ?? 0);
|
|
289
|
-
const
|
|
289
|
+
const proofTested = Number(enrichedPayload.summary?.proofTested ?? 0);
|
|
290
290
|
const total = Number(enrichedPayload.summary?.total ?? 0);
|
|
291
291
|
return {
|
|
292
292
|
content: [
|
|
293
293
|
{
|
|
294
294
|
type: "text",
|
|
295
|
-
text: `Coverage summary: ${fullyCovered} structurally covered and ${
|
|
295
|
+
text: `Coverage summary: ${fullyCovered} structurally covered and ${proofTested} tested end to end out of ${total}.`,
|
|
296
296
|
},
|
|
297
297
|
],
|
|
298
298
|
structuredContent: enrichedPayload,
|
|
@@ -306,7 +306,7 @@ export async function executeCoverage(input, context) {
|
|
|
306
306
|
export const coverageSpec = {
|
|
307
307
|
name: "kb_coverage",
|
|
308
308
|
cliName: "coverage",
|
|
309
|
-
description: "Generate curated structural coverage and conservative end-to-end requirement proof reports for requirements, symbols, or grouped types. Use it to ask which requirements are
|
|
309
|
+
description: "Generate curated structural coverage and conservative end-to-end requirement proof reports for requirements, symbols, or grouped types. Use it to ask which requirements are tested end to end, how strong each requirement's evidence is (evidenceLevel: proved, tested, asserted or unverified), and what blocks the rest; use kb_find_gaps for a plain list of missing links and kb_check for rule violations. Reports include the compatible repair plan plus typed kibi.migration-plan.v2 actions; semantic and E2E actions remain review/execution work. Paginated plans identify incomplete scope and no mutation occurs.",
|
|
310
310
|
businessInputSchema: {
|
|
311
311
|
type: "object",
|
|
312
312
|
properties: {
|
|
@@ -324,13 +324,13 @@ export const coverageSpec = {
|
|
|
324
324
|
includePassing: {
|
|
325
325
|
type: "boolean",
|
|
326
326
|
default: false,
|
|
327
|
-
description: "Also return rows that are already
|
|
327
|
+
description: "Also return rows that are already tested or not applicable. By default only rows that still need repair are returned.",
|
|
328
328
|
},
|
|
329
329
|
statuses: {
|
|
330
330
|
type: "array",
|
|
331
331
|
items: {
|
|
332
332
|
type: "string",
|
|
333
|
-
enum: ["
|
|
333
|
+
enum: ["tested", "missing", "unresolved", "not_applicable"],
|
|
334
334
|
},
|
|
335
335
|
description: "Requirement proof-status filter (req mode): include only rows whose proofStatus is listed. Selecting statuses implies include-passing; not_applicable rows carry their typed applicability reason in proofStages.applicability.reason. The summary always reflects the whole KB.",
|
|
336
336
|
},
|
|
@@ -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.1
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -85,8 +85,9 @@ requirement with its statement (before and after for a rewrite), firmness,
|
|
|
85
85
|
origin, scenarios and proof state. Put it in your reply unchanged (in the
|
|
86
86
|
messaging tool's message when replies go through one), then add one or two
|
|
87
87
|
sentences on why the requirements changed. Offer the full page with
|
|
88
|
-
`kibi signoff --format html --open`, or
|
|
89
|
-
|
|
88
|
+
`kibi signoff --format html --open`, or publish `.kb/briefs/signoff/latest.html`
|
|
89
|
+
as a rendered page when your host has a page tool (the Artifact tool in Claude
|
|
90
|
+
apps); never attach the `.html` as a file, which chat apps show as raw source;
|
|
90
91
|
past 15 requirements the Markdown stops and only the page lists them all.
|
|
91
92
|
Host details: `kibi-decisions`, `resources/signoff-views.md`. `--no-proof` skips the proof lookup, which reads coverage and is slow
|
|
92
93
|
on a large knowledge base. The summary is not an approval: never set
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-decisions
|
|
3
3
|
name: kibi-decisions
|
|
4
4
|
description: "Use when the person states a rule or decision (must, never, always, from now on, we decided), when a Kibi hook asks to confirm or warns about an edit to code that implements a firm requirement, when the Stop hook says source files changed but nothing was recorded, when kb_check quotes requirement_statement_unverified, or when a request conflicts with a recorded requirement or ADR. Covers reading firmness and origin, recording a person's rule as firm with origin.ref, superseding with a Why this changed section, the kb_compile_intent unresolved/reviewCandidates/conflictReviews loop, asking before overriding a firm rule, and putting decisions to the person as one numbered kibi signoff --questions view."
|
|
5
|
-
version: 1.2.
|
|
5
|
+
version: 1.2.1
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -13,7 +13,8 @@ statements and lists that render in any chat or messaging surface. Put it in
|
|
|
13
13
|
your reply unchanged: never wrap it in a code block, summarize it or retell a
|
|
14
14
|
requirement in your own words. Every run also writes
|
|
15
15
|
`.kb/briefs/signoff/latest.json`, `latest.md` and `latest.html` (git-ignored);
|
|
16
|
-
`latest.html` is a self-contained page with the full view
|
|
16
|
+
`latest.html` is a self-contained page with the full view, meant to be opened
|
|
17
|
+
in a browser or published as a page, not attached as a file.
|
|
17
18
|
|
|
18
19
|
## Showing it on your host
|
|
19
20
|
|
|
@@ -21,7 +22,7 @@ requirement in your own words. Every run also writes
|
|
|
21
22
|
| --- | --- |
|
|
22
23
|
| Claude Code, Codex, Cursor, ZCode, VS Code chat | Paste the default output; `/kibi-signoff` (Claude Code, Cursor, ZCode) runs it. Offer `kibi signoff --format html --open` for the page |
|
|
23
24
|
| OpenCode terminal | `kibi signoff --format md` and paste the fenced block unchanged: kibi-opencode draws it as a card, and `/kibi-signoff` reopens it |
|
|
24
|
-
| Replies sent through a messaging tool (cloud or project threads, chat bots) | Pass the default output as the message text, and
|
|
25
|
+
| Replies sent through a messaging tool (cloud or project threads, chat bots) | Pass the default output as the message text. Share `latest.html` only as a rendered page: in Claude apps (claude.ai, the mobile and desktop apps, Claude Code on the web) publish it with the Artifact tool and give its link. Never attach the `.html` as a file: the Claude apps, Slack and most chat apps show it as raw source or a download. With no page tool, the message text is the whole view |
|
|
25
26
|
| VS Code or Cursor with the kibi-vscode extension | The **Kibi: Show Requirements Signoff** panel follows every run |
|
|
26
27
|
| Remote machine, no browser | Give the person the path of `latest.html` |
|
|
27
28
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-freshness
|
|
3
3
|
name: kibi-freshness
|
|
4
4
|
description: Check exact Git attachment, branch migration/quarantine, compiled-store freshness, source linkage, and repair state before decisions or writes.
|
|
5
|
-
version: 2.
|
|
5
|
+
version: 2.1.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -53,7 +53,7 @@ echo '{}' | npx --no-install kibi status --input -
|
|
|
53
53
|
`committed_with_repairs`, follow required typed `nextActions`; never retry the
|
|
54
54
|
original operation.
|
|
55
55
|
|
|
56
|
-
For every freshness, branch, or completion question, call `kb_status` first, then `kb_query` the entities and source files that status names, then `kb_check` as the last Kibi call before answering. Never skip the query step, even when status alone seems to answer the question. If another query or write follows a check, run `kb_check` again before answering. When asked whether requirements are consistent or proven, run `kb_query`, then `kb_check` with the domain-contradictions
|
|
56
|
+
For every freshness, branch, or completion question, call `kb_status` first, then `kb_query` the entities and source files that status names, then `kb_check` as the last Kibi call before answering. Never skip the query step, even when status alone seems to answer the question. If another query or write follows a check, run `kb_check` again before answering. When asked whether requirements are consistent or proven, run `kb_query`, then `kb_check` with the rules `domain-contradictions`, `kb-consistency` and `kb-consistency-unresolved`, then `kb_coverage`, and read whether the analysis was complete. `domain-contradictions` compares facts two at a time; `kb-consistency` checks every fact of a property together, so a clean pairwise result is not proof. Report a `kb-consistency` violation as a conflict, name every requirement it lists, and give superseding or changing one of them as the next step; never edit or delete facts to make the check pass. Report a context `kb-consistency-unresolved` names as unresolved, never as consistent, with the step that would make it comparable. Report any unmodeled or unknown clause as incomplete analysis, not as consistent. Only when every clause is fully modeled and compatible, state plainly that no conflict was found. For authorized knowledge changes, keep the exact supplied target and intended relationship edges, and discover and query those targets first. Validate the payload with `kb_upsert` and `dryRun: true`, then perform the authorized `kb_upsert` with that same payload and read the result back exactly before the final checks. A passing dry run is validation, not completion. Distinct authorized payloads may need several sequential writes, each validated and read back, but never retry a mutation that already committed. If a mutation returns `committed_with_repairs`, follow its typed `nextActions` instead of repeating the original operation.
|
|
57
57
|
|
|
58
58
|
## Guidance
|
|
59
59
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-usage
|
|
3
3
|
name: Kibi Usage
|
|
4
4
|
description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
|
|
5
|
-
version: 2.
|
|
5
|
+
version: 2.24.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -168,7 +168,7 @@ End every task with these five independent fields:
|
|
|
168
168
|
taskOutcome: complete | interim | blocked
|
|
169
169
|
kbState: clean_fresh | stale | dirty | legacy_compat | not_evaluated
|
|
170
170
|
verificationState: fresh | dirty | unavailable | not_evaluated
|
|
171
|
-
proofState:
|
|
171
|
+
proofState: tested | mixed | unresolved | not_evaluated
|
|
172
172
|
limitationDisposition: none | accepted | unaccepted | not_applicable
|
|
173
173
|
```
|
|
174
174
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Proof and Verification Workflow
|
|
2
2
|
|
|
3
|
-
Use this resource when a requirement must be
|
|
3
|
+
Use this resource when a requirement must be tested end to end before handoff, when
|
|
4
4
|
wiring a proof-bearing test, or when `kb_ingest_proof` or `kibi prove`
|
|
5
5
|
rejected evidence.
|
|
6
6
|
|
|
@@ -97,9 +97,9 @@ Cosmetic edits (descriptions, labels) never stale proof. Execution-relevant
|
|
|
97
97
|
edits (command, artifact, targets, options, bindings, contract) change the
|
|
98
98
|
effective fingerprint and do.
|
|
99
99
|
|
|
100
|
-
## What counts toward
|
|
100
|
+
## What counts toward proofTested
|
|
101
101
|
|
|
102
|
-
A requirement
|
|
102
|
+
A requirement reaches `proofStatus: tested` only through its scenarios' tests, and a scenario test
|
|
103
103
|
counts only when it is an **end-to-end** test with a valid, fresh, passing
|
|
104
104
|
receipt for the current snapshot.
|
|
105
105
|
|
|
@@ -109,7 +109,7 @@ receipt for the current snapshot.
|
|
|
109
109
|
`source` path contains `e2e`) counts as end-to-end; anything else is
|
|
110
110
|
`unknown` scope.
|
|
111
111
|
- A `unit` or `integration` receipt is still recorded on the test entity, but
|
|
112
|
-
it does not move `
|
|
112
|
+
it does not move `proofTested` for a behavioural requirement: the
|
|
113
113
|
requirement keeps the `missing_passing_e2e` gap in `proofGaps`. The one
|
|
114
114
|
exception is a scenario whose specifying requirements are all grounded only
|
|
115
115
|
in component-scope UI predicates (`ui_pattern`, `same_pattern`,
|
|
@@ -120,6 +120,38 @@ receipt for the current snapshot.
|
|
|
120
120
|
receipt does not change it, and a `passing` status without a fresh receipt
|
|
121
121
|
proves nothing.
|
|
122
122
|
|
|
123
|
+
## Evidence levels
|
|
124
|
+
|
|
125
|
+
Every requirement row also carries `evidenceLevel`, the strength of what backs
|
|
126
|
+
it, and `evidence`, the entries that earned it (each with `kind`, `scope` and
|
|
127
|
+
`level`):
|
|
128
|
+
|
|
129
|
+
- `proved`: a re-checkable certificate covers every case. No proof kind issues
|
|
130
|
+
certificates yet, so nothing reaches it today.
|
|
131
|
+
- `tested`: `proofStatus` is `tested`; fresh E2E receipts cover every linked
|
|
132
|
+
scenario.
|
|
133
|
+
- `asserted`: a person stands behind the statement (approved, or firm by
|
|
134
|
+
`firmness` or a non-agent origin) but nothing current checks it.
|
|
135
|
+
- `unverified`: an agent wrote it, no person approved it, nothing checks it.
|
|
136
|
+
|
|
137
|
+
Report the level as it is. Never call an `asserted` or `unverified`
|
|
138
|
+
requirement proven or tested, and never call `tested` proved. Firmness is a
|
|
139
|
+
separate axis: it says how sure the person is, not how strong the evidence is.
|
|
140
|
+
|
|
141
|
+
## Knowledge-base certificates
|
|
142
|
+
|
|
143
|
+
`kb_check` (`kibi check`) proves facts about the KB itself in its
|
|
144
|
+
`kb-consistency` rule and re-checks each answer with an independent checker:
|
|
145
|
+
property facts are consistent (a model per subject, property and scope, or an
|
|
146
|
+
irreducible contradiction core), predicate facts and allow/deny decisions are
|
|
147
|
+
consistent, and stored rules are stratified. It catches facts that contradict
|
|
148
|
+
only together, which the pairwise `domain-contradictions` rule misses. A
|
|
149
|
+
`kb-consistency` violation names the core facts and the requirements behind
|
|
150
|
+
them: supersede or change one of those requirements; never edit the facts so
|
|
151
|
+
the check passes. Quote a `kb-consistency-unresolved` diagnostic as
|
|
152
|
+
unresolved, never as consistent. Opposing rule pairs and scenario
|
|
153
|
+
feasibility are not certified yet; their own rules still decide them.
|
|
154
|
+
|
|
123
155
|
## Attempt semantics (factual, never optimistic)
|
|
124
156
|
|
|
125
157
|
- `attempts: {status: "complete", entries: [...]}` — known history; the
|
|
@@ -9,7 +9,7 @@ success flag):
|
|
|
9
9
|
taskOutcome: complete | interim | blocked
|
|
10
10
|
kbState: clean_fresh | stale | dirty | legacy_compat | not_evaluated
|
|
11
11
|
verificationState: fresh | dirty | unavailable | not_evaluated
|
|
12
|
-
proofState:
|
|
12
|
+
proofState: tested | mixed | unresolved | not_evaluated
|
|
13
13
|
limitationDisposition: none | accepted | unaccepted | not_applicable
|
|
14
14
|
```
|
|
15
15
|
|
|
@@ -341,7 +341,7 @@ h1 span {
|
|
|
341
341
|
content: "";
|
|
342
342
|
background: var(--amber);
|
|
343
343
|
}
|
|
344
|
-
.requirement--
|
|
344
|
+
.requirement--tested::before {
|
|
345
345
|
background: var(--green);
|
|
346
346
|
}
|
|
347
347
|
.requirement--unresolved::before {
|
|
@@ -356,6 +356,13 @@ h1 span {
|
|
|
356
356
|
align-items: start;
|
|
357
357
|
justify-content: space-between;
|
|
358
358
|
}
|
|
359
|
+
.evidence-level {
|
|
360
|
+
margin-left: 6px;
|
|
361
|
+
opacity: 0.75;
|
|
362
|
+
font-weight: 700;
|
|
363
|
+
text-transform: uppercase;
|
|
364
|
+
letter-spacing: .06em;
|
|
365
|
+
}
|
|
359
366
|
.requirement__id {
|
|
360
367
|
margin-bottom: 7px;
|
|
361
368
|
color: var(--muted);
|
|
@@ -380,7 +387,7 @@ h1 span {
|
|
|
380
387
|
letter-spacing: .07em;
|
|
381
388
|
text-transform: uppercase;
|
|
382
389
|
}
|
|
383
|
-
.proof-badge--
|
|
390
|
+
.proof-badge--tested {
|
|
384
391
|
border-color: rgba(98, 230, 167, 0.25);
|
|
385
392
|
color: var(--green);
|
|
386
393
|
background: rgba(98, 230, 167, 0.08);
|
|
@@ -1001,7 +1008,7 @@ h1 {
|
|
|
1001
1008
|
.requirement::before {
|
|
1002
1009
|
background: var(--warning);
|
|
1003
1010
|
}
|
|
1004
|
-
.requirement--
|
|
1011
|
+
.requirement--tested::before {
|
|
1005
1012
|
background: var(--success);
|
|
1006
1013
|
}
|
|
1007
1014
|
.requirement--unresolved::before {
|
|
@@ -1024,7 +1031,7 @@ h1 {
|
|
|
1024
1031
|
background: rgba(242, 184, 75, 0.07);
|
|
1025
1032
|
font: 800 9px / 1.2 var(--mono);
|
|
1026
1033
|
}
|
|
1027
|
-
.proof-badge--
|
|
1034
|
+
.proof-badge--tested {
|
|
1028
1035
|
border-color: rgba(99, 201, 154, 0.3);
|
|
1029
1036
|
color: var(--success);
|
|
1030
1037
|
background: rgba(99, 201, 154, 0.07);
|
|
@@ -15,7 +15,7 @@ export type HtmlReportInput = Readonly<{
|
|
|
15
15
|
generatedAt: Date;
|
|
16
16
|
repository?: ReportRepository;
|
|
17
17
|
}>;
|
|
18
|
-
export declare function firstFailingProofGate(gates: readonly ProofGateKey[], passes: (gate: ProofGateKey) => boolean): ProofGateKey | "
|
|
19
|
-
export declare function earliestUnmetGate(row: UnknownRecord): ProofGateKey | "
|
|
18
|
+
export declare function firstFailingProofGate(gates: readonly ProofGateKey[], passes: (gate: ProofGateKey) => boolean): ProofGateKey | "tested";
|
|
19
|
+
export declare function earliestUnmetGate(row: UnknownRecord): ProofGateKey | "tested";
|
|
20
20
|
export declare function renderHtmlReport(input: HtmlReportInput): string;
|
|
21
21
|
//# sourceMappingURL=html-report.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-report.d.ts","sourceRoot":"","sources":["../../src/report/html-report.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,gBAAgB,EAMtB,MAAM,iBAAiB,CAAC;AAGzB,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAuB9D,eAAO,MAAM,UAAU,6FACqE,CAAC;AAG7F,eAAO,MAAM,wBAAwB,gEAC0B,CAAC;AAEhE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,OAAO,EAAE,aAAa,CAAC;IACvB,IAAI,EAAE,SAAS,aAAa,EAAE,CAAC;IAC/B,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB,CAAC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,YAAY,EAAE,kBAAkB,CAAC;IACjC,OAAO,EAAE,kBAAkB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,IAAI,CAAC;IAClB,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B,CAAC,CAAC;AAkNH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,MAAM,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,GACtC,YAAY,GAAG,QAAQ,CAKzB;AAID,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,GAAG,QAAQ,CAM7E;
|
|
1
|
+
{"version":3,"file":"html-report.d.ts","sourceRoot":"","sources":["../../src/report/html-report.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,YAAY,EAGlB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,gBAAgB,EAMtB,MAAM,iBAAiB,CAAC;AAGzB,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAuB9D,eAAO,MAAM,UAAU,6FACqE,CAAC;AAG7F,eAAO,MAAM,wBAAwB,gEAC0B,CAAC;AAEhE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,OAAO,EAAE,aAAa,CAAC;IACvB,IAAI,EAAE,SAAS,aAAa,EAAE,CAAC;IAC/B,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB,CAAC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,YAAY,EAAE,kBAAkB,CAAC;IACjC,OAAO,EAAE,kBAAkB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,IAAI,CAAC;IAClB,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B,CAAC,CAAC;AAkNH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,MAAM,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,GACtC,YAAY,GAAG,QAAQ,CAKzB;AAID,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,GAAG,QAAQ,CAM7E;AAqZD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAuM/D"}
|
|
@@ -143,7 +143,7 @@ function implementationOwned(stages) {
|
|
|
143
143
|
return productionSymbols.every((symbol) => !missingCoordinates.has(symbol));
|
|
144
144
|
}
|
|
145
145
|
function passesProofGate(row, gate) {
|
|
146
|
-
if (row.proofStatus === "
|
|
146
|
+
if (row.proofStatus === "tested")
|
|
147
147
|
return true;
|
|
148
148
|
const stages = record(row.proofStages);
|
|
149
149
|
if (gate === "semantic") {
|
|
@@ -158,7 +158,7 @@ function passesProofGate(row, gate) {
|
|
|
158
158
|
if (gate === "e2e") {
|
|
159
159
|
return stagePassed(stages, "scenarioTests") && hasEndToEndTest(stages);
|
|
160
160
|
}
|
|
161
|
-
return row.proofStatus === "
|
|
161
|
+
return row.proofStatus === "tested";
|
|
162
162
|
}
|
|
163
163
|
function proofGates(rows) {
|
|
164
164
|
const definitions = [
|
|
@@ -197,13 +197,13 @@ export function firstFailingProofGate(gates, passes) {
|
|
|
197
197
|
if (!passes(gate))
|
|
198
198
|
return gate;
|
|
199
199
|
}
|
|
200
|
-
return "
|
|
200
|
+
return "tested";
|
|
201
201
|
}
|
|
202
202
|
// implements REQ-kibi-html-health-report
|
|
203
203
|
// covered_by TEST-kibi-html-health-report
|
|
204
204
|
export function earliestUnmetGate(row) {
|
|
205
|
-
if (row.proofStatus === "
|
|
206
|
-
return "
|
|
205
|
+
if (row.proofStatus === "tested")
|
|
206
|
+
return "tested";
|
|
207
207
|
return firstFailingProofGate(["semantic", "scenario", "implementation", "e2e", "evidence"], (gate) => passesProofGate(row, gate));
|
|
208
208
|
}
|
|
209
209
|
function evidenceStage(passingE2e, testSources, repository) {
|
|
@@ -401,15 +401,15 @@ function rowSeverity(row) {
|
|
|
401
401
|
return 0;
|
|
402
402
|
if (gaps.includes("stale_proof_receipt"))
|
|
403
403
|
return 1;
|
|
404
|
-
if (row.proofStatus !== "
|
|
404
|
+
if (row.proofStatus !== "tested")
|
|
405
405
|
return 2;
|
|
406
406
|
return 3;
|
|
407
407
|
}
|
|
408
408
|
function rowStates(row) {
|
|
409
409
|
const states = new Set();
|
|
410
410
|
const gaps = strings(row.proofGaps);
|
|
411
|
-
if (row.proofStatus === "
|
|
412
|
-
states.add("
|
|
411
|
+
if (row.proofStatus === "tested")
|
|
412
|
+
states.add("tested");
|
|
413
413
|
else
|
|
414
414
|
states.add("attention");
|
|
415
415
|
if (gaps.includes("stale_proof_receipt"))
|
|
@@ -430,8 +430,8 @@ function renderRequirement(row, repository) {
|
|
|
430
430
|
const proofStatus = text(row.proofStatus, "missing");
|
|
431
431
|
const proofGaps = strings(row.proofGaps);
|
|
432
432
|
const proofAdvisories = strings(row.proofAdvisories);
|
|
433
|
-
const blockingGaps = proofStatus === "
|
|
434
|
-
const advisories = proofStatus === "
|
|
433
|
+
const blockingGaps = proofStatus === "tested" ? [] : proofGaps;
|
|
434
|
+
const advisories = proofStatus === "tested"
|
|
435
435
|
? [
|
|
436
436
|
...proofAdvisories,
|
|
437
437
|
...proofGaps.filter((gap) => !proofAdvisories.includes(gap)),
|
|
@@ -439,7 +439,8 @@ function renderRequirement(row, repository) {
|
|
|
439
439
|
: proofAdvisories;
|
|
440
440
|
const conflicts = records(record(record(row.proofStages).contradictions).conflicts).filter((conflict) => text(conflict.status) === "contradiction");
|
|
441
441
|
const stages = requirementStages(row, repository);
|
|
442
|
-
const badgeLabel = proofStatus === "
|
|
442
|
+
const badgeLabel = proofStatus === "tested" ? "Tested" : "Needs attention";
|
|
443
|
+
const evidenceLevel = text(row.evidenceLevel, "unverified");
|
|
443
444
|
const requirementSource = sourceCoordinate({
|
|
444
445
|
path: text(record(record(row.proofStages).sourceCoordinates).requirementPath, text(row.source)),
|
|
445
446
|
}) ?? sourceCoordinate({ path: text(row.source) });
|
|
@@ -447,7 +448,7 @@ function renderRequirement(row, repository) {
|
|
|
447
448
|
return `<article class="requirement requirement--${escapeHtml(proofStatus)}" data-state="${rowStates(row)}" data-gate="${escapeHtml(gate)}">
|
|
448
449
|
<header class="requirement__header">
|
|
449
450
|
<div>
|
|
450
|
-
<div class="requirement__id">${linkedLabel(id, sourceWebUrl(repository, requirementSource))}</div>
|
|
451
|
+
<div class="requirement__id">${linkedLabel(id, sourceWebUrl(repository, requirementSource))} <span class="evidence-level evidence-level--${escapeHtml(evidenceLevel)}" title="Evidence level">${escapeHtml(evidenceLevel)}</span></div>
|
|
451
452
|
<h3>${linkedLabel(title, sourceWebUrl(repository, requirementSource))}</h3>
|
|
452
453
|
</div>
|
|
453
454
|
<span class="proof-badge proof-badge--${escapeHtml(proofStatus)}">${escapeHtml(badgeLabel)}</span>
|
|
@@ -458,6 +459,11 @@ function renderRequirement(row, repository) {
|
|
|
458
459
|
${renderIssueList(advisories, "proof-advisories", "advisory", "advisories")}
|
|
459
460
|
</article>`;
|
|
460
461
|
}
|
|
462
|
+
// implements REQ-kibi-evidence-levels
|
|
463
|
+
function evidenceCount(rows, level) {
|
|
464
|
+
return rows.filter((row) => text(row.evidenceLevel, "unverified") === level)
|
|
465
|
+
.length;
|
|
466
|
+
}
|
|
461
467
|
function metric(label, value, tone = "") {
|
|
462
468
|
return `<div class="metric${tone ? ` metric--${tone}` : ""}"><span>${escapeHtml(label)}</span><strong>${value.toLocaleString("en-US")}</strong></div>`;
|
|
463
469
|
}
|
|
@@ -513,7 +519,7 @@ function reportIdentity(input) {
|
|
|
513
519
|
function renderFilters(counts) {
|
|
514
520
|
const labels = {
|
|
515
521
|
all: "All",
|
|
516
|
-
|
|
522
|
+
tested: "Tested",
|
|
517
523
|
attention: "Needs attention",
|
|
518
524
|
stale: "Stale evidence",
|
|
519
525
|
contradiction: "Contradictions",
|
|
@@ -537,10 +543,10 @@ export function renderHtmlReport(input) {
|
|
|
537
543
|
const total = count(summary.total);
|
|
538
544
|
const notApplicable = count(summary.proofNotApplicable);
|
|
539
545
|
const currentRequirements = Math.max(0, total - notApplicable);
|
|
540
|
-
const
|
|
546
|
+
const tested = count(summary.proofTested);
|
|
541
547
|
const proofPercent = currentRequirements === 0
|
|
542
548
|
? 0
|
|
543
|
-
: Math.round((
|
|
549
|
+
: Math.round((tested / currentRequirements) * 100);
|
|
544
550
|
const missingScenarios = currentRows.filter((row) => strings(row.proofGaps).includes("missing_scenario")).length;
|
|
545
551
|
const staleEvidence = currentRows.filter((row) => strings(row.proofGaps).includes("stale_proof_receipt")).length;
|
|
546
552
|
const withoutImplementation = currentRows.filter((row) => strings(row.proofGaps).includes("missing_production_symbol")).length;
|
|
@@ -561,12 +567,10 @@ export function renderHtmlReport(input) {
|
|
|
561
567
|
})));
|
|
562
568
|
const identity = reportIdentity({ ...input, repository });
|
|
563
569
|
const faviconHref = renderKibiFaviconDataUri();
|
|
564
|
-
const scoreLabel = currentRequirements === 0
|
|
565
|
-
? "No current requirements"
|
|
566
|
-
: "Strict proof coverage";
|
|
570
|
+
const scoreLabel = currentRequirements === 0 ? "No current requirements" : "Tested end to end";
|
|
567
571
|
const scoreRatio = currentRequirements === 0
|
|
568
572
|
? "No current requirements to prove"
|
|
569
|
-
: `${
|
|
573
|
+
: `${tested.toLocaleString("en-US")} of ${currentRequirements.toLocaleString("en-US")} current requirements fully tested end-to-end`;
|
|
570
574
|
return `<!doctype html>
|
|
571
575
|
<html lang="en">
|
|
572
576
|
<head>
|
|
@@ -596,7 +600,7 @@ export function renderHtmlReport(input) {
|
|
|
596
600
|
<h1>Intent to proof,<br>without the gaps.</h1>
|
|
597
601
|
<p>Kibi compiles product intent into an inspectable chain of semantics, scenarios, implementation ownership, end-to-end tests, and fresh evidence.</p>
|
|
598
602
|
</div>
|
|
599
|
-
<div class="score" aria-label="${proofPercent}%
|
|
603
|
+
<div class="score" aria-label="${proofPercent}% tested end to end, ${tested} of ${currentRequirements} current requirements fully tested end-to-end">
|
|
600
604
|
<div class="score__value">${proofPercent}<span>%</span></div>
|
|
601
605
|
<div class="score__label">${escapeHtml(scoreLabel)}</div>
|
|
602
606
|
<div class="score__ratio">${escapeHtml(scoreRatio)}</div>
|
|
@@ -613,7 +617,9 @@ export function renderHtmlReport(input) {
|
|
|
613
617
|
</section>
|
|
614
618
|
<section class="metrics" aria-label="Requirement health summary">
|
|
615
619
|
${metric("Requirements", currentRequirements)}
|
|
616
|
-
${metric("
|
|
620
|
+
${metric("Tested end to end", tested, "good")}
|
|
621
|
+
${metric("Asserted, no current test", evidenceCount(currentRows, "asserted"), evidenceCount(currentRows, "asserted") ? "warn" : "")}
|
|
622
|
+
${metric("Unverified", evidenceCount(currentRows, "unverified"), evidenceCount(currentRows, "unverified") ? "warn" : "")}
|
|
617
623
|
${metric("Missing scenarios", missingScenarios, missingScenarios ? "warn" : "")}
|
|
618
624
|
${metric("Stale E2E evidence", staleEvidence, staleEvidence ? "warn" : "")}
|
|
619
625
|
${metric("Contradictions", contradictions.length, contradictions.length ? "bad" : "")}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export declare const REPORT_FILTERS: readonly ["all", "
|
|
1
|
+
export declare const REPORT_FILTERS: readonly ["all", "tested", "attention", "stale", "contradiction"];
|
|
2
2
|
export type ReportFilter = (typeof REPORT_FILTERS)[number];
|
|
3
3
|
export declare const PROOF_GATE_KEYS: readonly ["semantic", "scenario", "implementation", "e2e", "evidence"];
|
|
4
4
|
export type ProofGateKey = (typeof PROOF_GATE_KEYS)[number];
|
|
5
5
|
export type RequirementView = Readonly<{
|
|
6
6
|
text: string;
|
|
7
7
|
states: readonly string[];
|
|
8
|
-
earliestGate: ProofGateKey | "
|
|
8
|
+
earliestGate: ProofGateKey | "tested";
|
|
9
9
|
}>;
|
|
10
10
|
export type ReportViewQuery = Readonly<{
|
|
11
11
|
query: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const REPORT_FILTERS = [
|
|
2
2
|
"all",
|
|
3
|
-
"
|
|
3
|
+
"tested",
|
|
4
4
|
"attention",
|
|
5
5
|
"stale",
|
|
6
6
|
"contradiction",
|
|
@@ -24,7 +24,7 @@ export function matchesReportView(row, view) {
|
|
|
24
24
|
export function reportFilterCounts(rows) {
|
|
25
25
|
return {
|
|
26
26
|
all: rows.length,
|
|
27
|
-
|
|
27
|
+
tested: rows.filter((row) => row.states.includes("tested")).length,
|
|
28
28
|
attention: rows.filter((row) => row.states.includes("attention")).length,
|
|
29
29
|
stale: rows.filter((row) => row.states.includes("stale")).length,
|
|
30
30
|
contradiction: rows.filter((row) => row.states.includes("contradiction"))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/signoff/collect.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAIL,KAAK,YAAY,EAEjB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAGrB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AASpB,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEhD,2DAA2D;AAC3D,MAAM,MAAM,oBAAoB,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAE1E,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,qEAAqE;IACrE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC;IAC1C,0EAA0E;IAC1E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtE,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAC7D,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC,CAAC;AAuCH,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAEpE;AAyGD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,YAAY,EACnB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/signoff/collect.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAIL,KAAK,YAAY,EAEjB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAGrB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AASpB,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEhD,2DAA2D;AAC3D,MAAM,MAAM,oBAAoB,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAE1E,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,qEAAqE;IACrE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC;IAC1C,0EAA0E;IAC1E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtE,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAC7D,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC,CAAC;AAuCH,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAEpE;AAyGD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,YAAY,EACnB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAiKzB;AAGD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,oBAAoB,CAAC,CA8B/B;AAGD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,SAAS,oBAAoB,EAAE,EACvC,GAAG,GAAE,MAAM,IAAuB,GACjC,gBAAgB,CA4BlB;AA+BD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,GACV,oBAAoB,EAAE,CAkDxB"}
|
package/dist/signoff/collect.js
CHANGED
|
@@ -151,6 +151,10 @@ export async function collectSignoffSummary(workspaceRoot, scope, deps = {}) {
|
|
|
151
151
|
: undefined;
|
|
152
152
|
const firmness = firmnessOf(entity);
|
|
153
153
|
const origin = entity.origin;
|
|
154
|
+
// origin.approved_by records who approved an agent-written requirement,
|
|
155
|
+
// the field its evidence level and agent-requirement-unapproved read. The
|
|
156
|
+
// top-level approved_by approves an exception and is not read here.
|
|
157
|
+
const approvedBy = origin?.approved_by;
|
|
154
158
|
return {
|
|
155
159
|
id: entity.id,
|
|
156
160
|
title: flat(entity.title ?? entity.id),
|
|
@@ -163,7 +167,7 @@ export async function collectSignoffSummary(workspaceRoot, scope, deps = {}) {
|
|
|
163
167
|
...(firmness ? { firmness } : {}),
|
|
164
168
|
...(origin?.kind ? { originKind: origin.kind } : {}),
|
|
165
169
|
...(origin?.ref ? { originRef: flat(origin.ref) } : {}),
|
|
166
|
-
...(
|
|
170
|
+
...(approvedBy ? { approvedBy } : {}),
|
|
167
171
|
supersedes: outgoing(entity.id, "supersedes")
|
|
168
172
|
.map((id) => readRequirement(id))
|
|
169
173
|
.filter((ref) => ref !== undefined)
|
package/dist/signoff/html.js
CHANGED
|
@@ -30,7 +30,7 @@ h2{font-size:16px;margin:28px 0 10px;color:var(--accent)}
|
|
|
30
30
|
.badge{font-size:12px;padding:1px 8px;border-radius:999px;border:1px solid var(--rail);color:var(--muted)}
|
|
31
31
|
.badge--firm{border-color:var(--warn);color:var(--warn)}
|
|
32
32
|
.badge--exploratory{border-color:var(--signal);color:var(--signal)}
|
|
33
|
-
.badge--
|
|
33
|
+
.badge--tested{border-color:var(--ok);color:var(--ok)}
|
|
34
34
|
.badge--answered{border-color:var(--ok);color:var(--ok)}
|
|
35
35
|
.badge--approval{border-color:var(--signal);color:var(--signal);font-weight:600}
|
|
36
36
|
.callout{margin:12px 0 4px;padding:10px 14px;border:1px solid var(--signal);border-radius:8px;color:var(--text)}
|
|
@@ -98,8 +98,8 @@ function requirementCard(requirement, number) {
|
|
|
98
98
|
: requirement.scenarios
|
|
99
99
|
.map((scenario) => `<span class="id">${escapeHtml(scenario.id)}</span>${scenario.title === scenario.id ? "" : ` ${escapeHtml(scenario.title)}`}`)
|
|
100
100
|
.join("<br>")));
|
|
101
|
-
const
|
|
102
|
-
details.push(row("Proof", `<span class="badge${
|
|
101
|
+
const tested = requirement.proof?.gate === "tested";
|
|
102
|
+
details.push(row("Proof", `<span class="badge${tested ? " badge--tested" : ""}">${escapeHtml(proofLabel(requirement.proof))}</span>`));
|
|
103
103
|
for (const conflict of requirement.proof?.contradictions ?? []) {
|
|
104
104
|
details.push(row("Contradiction", `<span class="conflict">${escapeHtml(conflict)}</span>`));
|
|
105
105
|
}
|
package/dist/signoff/model.d.ts
CHANGED
|
@@ -30,11 +30,16 @@ export type SignoffStatementRef = Readonly<{
|
|
|
30
30
|
firmness?: SignoffFirmness;
|
|
31
31
|
}>;
|
|
32
32
|
export type SignoffProof = Readonly<{
|
|
33
|
-
/** Coverage proof status:
|
|
33
|
+
/** Coverage proof status: tested, missing, unresolved or not_applicable. */
|
|
34
34
|
status: string;
|
|
35
|
-
/** The earliest unmet proof gate, or "
|
|
35
|
+
/** The earliest unmet proof gate, or "tested". */
|
|
36
36
|
gate: string;
|
|
37
37
|
testCount: number;
|
|
38
|
+
/**
|
|
39
|
+
* How strong the evidence is: proved, tested, asserted (a person stands
|
|
40
|
+
* behind it, nothing current checks it) or unverified.
|
|
41
|
+
*/
|
|
42
|
+
evidenceLevel?: string;
|
|
38
43
|
contradictions: readonly string[];
|
|
39
44
|
}>;
|
|
40
45
|
export type SignoffRequirement = Readonly<{
|